forked from HelloZeroNet/ZeroNet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDiff.py
More file actions
48 lines (41 loc) · 1.45 KB
/
Copy pathDiff.py
File metadata and controls
48 lines (41 loc) · 1.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import io
import difflib
def sumLen(lines):
return sum(map(len, lines))
def diff(old, new, limit=False):
matcher = difflib.SequenceMatcher(None, old, new)
actions = []
size = 0
for tag, old_from, old_to, new_from, new_to in matcher.get_opcodes():
if tag == "insert":
new_line = new[new_from:new_to]
actions.append(("+", new_line))
size += sum(map(len, new_line))
elif tag == "equal":
actions.append(("=", sumLen(old[old_from:old_to])))
elif tag == "delete":
actions.append(("-", sumLen(old[old_from:old_to])))
elif tag == "replace":
actions.append(("-", sumLen(old[old_from:old_to])))
new_lines = new[new_from:new_to]
actions.append(("+", new_lines))
size += sumLen(new_lines)
if limit and size > limit:
return False
return actions
def patch(old_f, actions):
new_f = io.BytesIO()
for action, param in actions:
if type(action) is bytes:
action = action.decode()
if action == "=": # Same lines
new_f.write(old_f.read(param))
elif action == "-": # Delete lines
old_f.seek(param, 1) # Seek from current position
continue
elif action == "+": # Add lines
for add_line in param:
new_f.write(add_line)
else:
raise "Unknown action: %s" % action
return new_f