Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 135 lines 5.5 kB view raw
1import os 2import subprocess 3import re 4import logging 5import time 6import functools 7 8from Config import config 9from util import helper 10 11 12# Find files with extension in path 13def findfiles(path, find_ext): 14 def sorter(f1, f2): 15 f1 = f1[0].replace(path, "") 16 f2 = f2[0].replace(path, "") 17 if f1 == "": 18 return 1 19 elif f2 == "": 20 return -1 21 else: 22 return helper.cmp(f1.lower(), f2.lower()) 23 24 for root, dirs, files in sorted(os.walk(path, topdown=False), key=functools.cmp_to_key(sorter)): 25 for file in sorted(files): 26 file_path = root + "/" + file 27 file_ext = file.split(".")[-1] 28 if file_ext in find_ext and not file.startswith("all."): 29 yield file_path.replace("\\", "/") 30 31 32# Try to find coffeescript compiler in path 33def findCoffeescriptCompiler(): 34 coffeescript_compiler = None 35 try: 36 import distutils.spawn 37 coffeescript_compiler = helper.shellquote(distutils.spawn.find_executable("coffee")) + " --no-header -p" 38 except: 39 pass 40 if coffeescript_compiler: 41 return coffeescript_compiler 42 else: 43 return False 44 45 46# Generates: all.js: merge *.js, compile coffeescript, all.css: merge *.css, vendor prefix features 47def merge(merged_path): 48 merged_path = merged_path.replace("\\", "/") 49 merge_dir = os.path.dirname(merged_path) 50 s = time.time() 51 ext = merged_path.split(".")[-1] 52 if ext == "js": # If merging .js find .coffee too 53 find_ext = ["js", "coffee"] 54 else: 55 find_ext = [ext] 56 57 # If exist check the other files modification date 58 if os.path.isfile(merged_path): 59 merged_mtime = os.path.getmtime(merged_path) 60 else: 61 merged_mtime = 0 62 63 changed = {} 64 for file_path in findfiles(merge_dir, find_ext): 65 if os.path.getmtime(file_path) > merged_mtime + 1: 66 changed[file_path] = True 67 if not changed: 68 return # Assets not changed, nothing to do 69 70 old_parts = {} 71 if os.path.isfile(merged_path): # Find old parts to avoid unncessary recompile 72 merged_old = open(merged_path, "rb").read() 73 for match in re.findall(rb"(/\* ---- (.*?) ---- \*/(.*?)(?=/\* ----|$))", merged_old, re.DOTALL): 74 old_parts[match[1].decode()] = match[2].strip(b"\n\r") 75 76 logging.debug("Merging %s (changed: %s, old parts: %s)" % (merged_path, changed, len(old_parts))) 77 # Merge files 78 parts = [] 79 s_total = time.time() 80 for file_path in findfiles(merge_dir, find_ext): 81 file_relative_path = file_path.replace(merge_dir + "/", "") 82 parts.append(b"\n/* ---- %s ---- */\n\n" % file_relative_path.encode("utf8")) 83 if file_path.endswith(".coffee"): # Compile coffee script 84 if file_path in changed or file_relative_path not in old_parts: # Only recompile if changed or its not compiled before 85 if config.coffeescript_compiler is None: 86 config.coffeescript_compiler = findCoffeescriptCompiler() 87 if not config.coffeescript_compiler: 88 logging.error("No coffeescript compiler defined, skipping compiling %s" % merged_path) 89 return False # No coffeescript compiler, skip this file 90 91 # Replace / with os separators and escape it 92 file_path_escaped = helper.shellquote(file_path.replace("/", os.path.sep)) 93 94 if "%s" in config.coffeescript_compiler: # Replace %s with coffeescript file 95 command = config.coffeescript_compiler.replace("%s", file_path_escaped) 96 else: # Put coffeescript file to end 97 command = config.coffeescript_compiler + " " + file_path_escaped 98 99 # Start compiling 100 s = time.time() 101 compiler = subprocess.Popen(command, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) 102 out = compiler.stdout.read() 103 compiler.wait() 104 logging.debug("Running: %s (Done in %.2fs)" % (command, time.time() - s)) 105 106 # Check errors 107 if out and out.startswith(b"("): # No error found 108 parts.append(out) 109 else: # Put error message in place of source code 110 error = out 111 logging.error("%s Compile error: %s" % (file_relative_path, error)) 112 error_escaped = re.escape(error).replace(b"\n", b"\\n").replace(br"\\n", br"\n") 113 parts.append( 114 b"alert('%s compile error: %s');" % 115 (file_relative_path.encode(), error_escaped) 116 ) 117 else: # Not changed use the old_part 118 parts.append(old_parts[file_relative_path]) 119 else: # Add to parts 120 parts.append(open(file_path, "rb").read()) 121 122 merged = b"\n".join(parts) 123 if ext == "css": # Vendor prefix css 124 from lib.cssvendor import cssvendor 125 merged = cssvendor.prefix(merged) 126 merged = merged.replace(b"\r", b"") 127 open(merged_path, "wb").write(merged) 128 logging.debug("Merged %s (%.2fs)" % (merged_path, time.time() - s_total)) 129 130 131if __name__ == "__main__": 132 logging.getLogger().setLevel(logging.DEBUG) 133 os.chdir("..") 134 config.coffeescript_compiler = r'type "%s" | tools\coffee-node\bin\node.exe tools\coffee-node\bin\coffee --no-header -s -p' 135 merge("data/12Hw8rTgzrNo4DSh2AkqwPRqDyTticwJyH/js/all.js")