Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
at main 48 lines 1.5 kB view raw
1import io 2 3import difflib 4 5 6def sumLen(lines): 7 return sum(map(len, lines)) 8 9 10def diff(old, new, limit=False): 11 matcher = difflib.SequenceMatcher(None, old, new) 12 actions = [] 13 size = 0 14 for tag, old_from, old_to, new_from, new_to in matcher.get_opcodes(): 15 if tag == "insert": 16 new_line = new[new_from:new_to] 17 actions.append(("+", new_line)) 18 size += sum(map(len, new_line)) 19 elif tag == "equal": 20 actions.append(("=", sumLen(old[old_from:old_to]))) 21 elif tag == "delete": 22 actions.append(("-", sumLen(old[old_from:old_to]))) 23 elif tag == "replace": 24 actions.append(("-", sumLen(old[old_from:old_to]))) 25 new_lines = new[new_from:new_to] 26 actions.append(("+", new_lines)) 27 size += sumLen(new_lines) 28 if limit and size > limit: 29 return False 30 return actions 31 32 33def patch(old_f, actions): 34 new_f = io.BytesIO() 35 for action, param in actions: 36 if type(action) is bytes: 37 action = action.decode() 38 if action == "=": # Same lines 39 new_f.write(old_f.read(param)) 40 elif action == "-": # Delete lines 41 old_f.seek(param, 1) # Seek from current position 42 continue 43 elif action == "+": # Add lines 44 for add_line in param: 45 new_f.write(add_line) 46 else: 47 raise "Unknown action: %s" % action 48 return new_f