import glob import shutil import gzip import os import subprocess import platform Import("env") Import("projenv") # Überprüfe die Betriebssystemplattform if platform.system() == "Windows": # Setze die Pfade zu den Tools für Windows html_minifier_path = os.path.join(os.getenv("APPDATA"), "npm", "html-minifier.cmd") uglifyjs_path = os.path.join(os.getenv("APPDATA"), "npm", "uglifyjs.cmd") terser_path = os.path.join(os.getenv("APPDATA"), "npm", "terser.cmd") cssnano_path = os.path.join(os.getenv("APPDATA"), "npm", "cssnano.cmd") elif platform.system() == "Linux": # Setze die Namen der Tools für Linux html_minifier_path = "html-minifier" uglifyjs_path = "uglifyjs" terser_path = "terser" cssnano_path = "cssnano" else: # Hier könntest du weitere Bedingungen für andere Betriebssysteme hinzufügen raise Exception("Unterstütztes Betriebssystem nicht erkannt") def minify_html(input_path, output_path): subprocess.run([html_minifier_path, '--collapse-whitespace', '--remove-comments', input_path, '-o', output_path]) def minify_js(input_path, output_path): subprocess.run([terser_path, input_path, '-o', output_path, '-c', '-m']) def minify_css(input_path, output_path): subprocess.run([cssnano_path, '--no-discardUnused', input_path, output_path]) def process_file(src_path, dest_path): _, file_extension = os.path.splitext(src_path) # Extrahiere den Ordnerpfad im Zielverzeichnis dest_dir = os.path.dirname(dest_path) # Erstelle den Ordner und alle dazugehörigen Unterordner, falls sie nicht existieren os.makedirs(dest_dir, exist_ok=True) if file_extension.lower() == '.js': minify_js(src_path, dest_path) elif file_extension.lower() == '.css': minify_css(src_path, dest_path) elif file_extension.lower() in ['.html', '.htm']: minify_html(src_path, dest_path) else: # Kopiere nicht bearbeitbare Dateien direkt in den Zielordner shutil.copy2(src_path, dest_path) def strip_files(src_dir, dest_dir): # Erstelle den Zielordner und alle dazugehörigen Unterordner, falls sie nicht existieren os.makedirs(dest_dir, exist_ok=True) # Durchlaufe alle Dateien und Unterverzeichnisse im Quellordner for root, _, files in os.walk(src_dir): for filename in files: src_path = os.path.join(root, filename) dest_path = os.path.relpath(src_path, src_dir) dest_path = os.path.join(dest_dir, dest_path) # Verarbeite nur Dateien (keine Unterverzeichnisse) process_file(src_path, dest_path) def gzip_file(src_path, dst_path): with open(src_path, 'rb') as src, gzip.open(dst_path, 'wb') as dst: for chunk in iter(lambda: src.read(4096), b""): dst.write(chunk) def getListOfFiles(dirName): # create a list of file and sub directories # names in the given directory listOfFile = os.listdir(dirName) allFiles = list() # Iterate over all the entries for entry in listOfFile: # Create full path fullPath = os.path.join(dirName, entry) # If entry is a directory then get the list of files in this directory if os.path.isdir(fullPath): allFiles = allFiles + getListOfFiles(fullPath) else: allFiles.append(fullPath) return allFiles def remove_prefix(text, prefix): if text.startswith(prefix): return text[len(prefix):] return text # or whatever # Compress files from 'data_src/' to 'data/' def gzip_webfiles(source, target, env): # Filetypes to compress filetypes_to_gzip = ['.css', '.png', '.js', '.ico', '.woff2', '.json'] print('\nGZIP: Starting gzip-Process for LittleFS-Image...\n') data_src_dir_path = os.path.join(env.get('PROJECT_DIR'), 'data_src') data_temp_dir_path = os.path.join(env.get('PROJECT_DIR'), 'data_stripped') strip_files(data_src_dir_path, data_temp_dir_path) data_dir_path = env.get('PROJECT_DATA_DIR') # check if data and datasrc exist. If the first exists and not the second, it renames it if(os.path.exists(data_dir_path) and not os.path.exists(data_temp_dir_path)): print('GZIP: Directory "'+data_dir_path + '" exists, "'+data_temp_dir_path+'" is not found.') print('GZIP: Renaming "' + data_dir_path + '" to "' + data_temp_dir_path + '"') os.rename(data_dir_path, data_temp_dir_path) # Delete the 'data' directory if(os.path.exists(data_dir_path)): print('GZIP: Deleting the "data" directory ' + data_dir_path) shutil.rmtree(data_dir_path) # Recreate empty 'data' directory print('GZIP: Re-creating an empty data directory ' + data_dir_path) os.mkdir(data_dir_path) # Determine the files to compress files_to_copy = [] files_to_gzip = [] all_data_src = getListOfFiles(data_temp_dir_path) for file in all_data_src: file_name, file_extension = os.path.splitext(file) print(file_name + " has filetype " + file_extension) if file_extension in filetypes_to_gzip: files_to_gzip.append(file) else: filename_subdir = remove_prefix(file, data_temp_dir_path) files_to_copy.append(filename_subdir) for file in files_to_copy: print('GZIP: Copying file from: ' + data_temp_dir_path + file + ' to: ' + data_dir_path + file) os.makedirs(os.path.dirname(data_dir_path + file), exist_ok=True) shutil.copy(data_temp_dir_path + file, data_dir_path + file) # Compress and move files was_error = False try: for source_file_path in files_to_gzip: print('GZIP: compressing... ' + source_file_path) filename_subdir = remove_prefix(source_file_path, data_temp_dir_path) target_file_path = data_dir_path + filename_subdir os.makedirs(os.path.dirname(target_file_path), exist_ok=True) print('GZIP: Compressed... ' + target_file_path) gzip_file(source_file_path, target_file_path + ".gz") except IOError as e: was_error = True print('GZIP: Failed to compress file: ' + source_file_path) # print( 'GZIP: EXCEPTION... {}'.format( e ) ) if was_error: print('GZIP: Failure/Incomplete.\n') else: print('GZIP: Compressed correctly.\n') shutil.rmtree(data_temp_dir_path) return def gzip_binffiles(source, target, env): git_revision = popen('git rev-parse --short HEAD').read().strip() custom_flash_version = env.GetProjectOption("custom_flash_version", "0.99") # Format the target file name target_filename = f"filesystem_{custom_flash_version}_{git_revision}.fs" littlefsbin = target[0].get_abspath() targetbin = os.path.join(os.path.dirname(littlefsbin), target_filename) shutil.copyfile(littlefsbin, targetbin) gzip_file(targetbin, os.path.join(str(targetbin) + '.gz')) os.remove(targetbin) return # IMPORTANT, this needs to be added to call the routine env.AddPreAction('$BUILD_DIR/littlefs.bin', gzip_webfiles) env.AddPostAction('$BUILD_DIR/littlefs.bin', gzip_binffiles)