Forking what is left of ZeroNet and hopefully adding an AT Proto Frontend/Proxy
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