Skip to content

Commit 55c563f

Browse files
author
Hugo Osvaldo Barrera
authored
Merge pull request #893 from Intevation/conflict-resolution-interactive
Add contrib script to resolve conflicts
2 parents a5731b2 + 61edfc0 commit 55c563f

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env python3
2+
"""Ask user to resolve a vdirsyncer sync conflict interactively.
3+
4+
Needs a way to ask the user.
5+
The use of https://apps.kde.org/kdialog/ for GNU/Linix is hardcoded.
6+
7+
Depends on python>3.5 and KDialog.
8+
9+
Usage:
10+
Ensure the file executable and use it in the vdirsyncer.conf file, e.g.
11+
12+
conflict_resolution = ["command", "/home/bern/vdirsyncer/resolve_interactively.py"]
13+
14+
This file is Free Software under the following license:
15+
SPDX-License-Identifier: BSD-3-Clause
16+
SPDX-FileCopyrightText: 2021 Intevation GmbH <https://intevation.de>
17+
18+
"""
19+
import re
20+
import subprocess
21+
import sys
22+
from pathlib import Path
23+
24+
KDIALOG = "/usr/bin/kdialog"
25+
26+
SUMMARY_PATTERN = re.compile("^(SUMMARY:.*)$", re.MULTILINE)
27+
28+
29+
def get_summary(icalendar_text: str):
30+
"""Get the first SUMMARY: line from an iCalendar text.
31+
32+
Do not care about the line being continued.
33+
"""
34+
match = re.search(SUMMARY_PATTERN, icalendar_text)
35+
return match[1]
36+
37+
38+
def main(ical1_filename, ical2_filename):
39+
ical1 = ical1_filename.read_text()
40+
ical2 = ical2_filename.read_text()
41+
42+
additional_args = ["--yes-label", "take first"] # return code == 0
43+
additional_args += ["--no-label", "take second"] # return code == 1
44+
additional_args += ["--cancel-label", "do not resolve"] # return code == 2
45+
46+
r = subprocess.run(
47+
args=[
48+
KDIALOG,
49+
"--warningyesnocancel",
50+
"There was a sync conflict, do you prefer the first entry: \n"
51+
+ get_summary(ical1)
52+
+ "...\n(full contents: "
53+
+ str(ical1_filename)
54+
+ " )\n\nor the second entry: \n"
55+
+ get_summary(ical2)
56+
+ "...\n(full contents: "
57+
+ str(ical2_filename)
58+
+ " )?",
59+
]
60+
+ additional_args
61+
)
62+
63+
if r.returncode == 2:
64+
# cancel was pressed
65+
return # shall lead to items not changed, because not copied
66+
67+
if r.returncode == 0:
68+
# we want to take the first item, so overwrite the second
69+
ical2_filename.write_text(ical1)
70+
else: # r.returncode == 1, we want the second item, so overwrite the first
71+
ical1_filename.write_text(ical2)
72+
73+
74+
if len(sys.argv) != 3:
75+
sys.stdout.write(__doc__)
76+
else:
77+
main(Path(sys.argv[1]), Path(sys.argv[2]))

0 commit comments

Comments
 (0)