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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
#!/usr/bin/env python3
"""
Syncthing-GTK - DeviceEditorDialog
Universal dialog handler for all Syncthing settings and editing
"""
from gi.repository import Gtk
from syncthing_gtk.tools import check_device_id
from syncthing_gtk.tools import _ # gettext function
from syncthing_gtk.editordialog import EditorDialog, strip_v
import logging
log = logging.getLogger("DeviceEditor")
COLOR_NEW = "#A0A0A0"
VALUES = [ "vdeviceID", "vname", "vaddresses", "vcompression",
"vfolders", "vintroducer"
]
class DeviceEditorDialog(EditorDialog):
MESSAGES = {
# Displayed when device id is invalid
"vdeviceID" : _("The entered device ID does not look valid. It "
"should be a 52 character string consisting of letters and "
"numbers, with spaces and dashes being optional."),
}
def __init__(self, app, is_new, id=None):
EditorDialog.__init__(self, app,
"device-edit.glade",
"New Device" if is_new else "Edit Device"
)
self.id = id
self.is_new = is_new
#@Overrides
def get_value(self, key):
if key == "addresses":
return ",".join([ strip_v(x) for x in self.values[key]])
elif key == "deviceID":
return EditorDialog.get_value(self, key).strip(" \r\n\t")
elif key == "compression":
val = EditorDialog.get_value(self, key)
# For syncthing <= 0.10.25
if val in (True, "true"):
return "always"
elif val in (False, "false"):
return "never"
else:
return val
else:
return EditorDialog.get_value(self, key)
#@Overrides
def set_value(self, key, value):
if key == "addresses":
self.values[key] = [ strip_v(x) for x in value.split(",") ]
else:
return EditorDialog.set_value(self, key, value)
#@Overrides
def on_data_loaded(self):
try:
if self.is_new:
self.values = { strip_v(x) : "" for x in VALUES }
self.set_value("addresses", "dynamic")
self.set_value("compression", "metadata")
self.checks = {
"vdeviceID" : check_device_id,
}
if self.id != None:
# Pre-fill device id, if provided
self.set_value("deviceID", self.id)
else:
self.values = [ x for x in self.config["devices"] if x["deviceID"] == self.id ][0]
except KeyError as e:
# ID not found in configuration. This is practically impossible,
# so it's handled only by self-closing dialog.
log.exception(e)
self.close()
return
return self.display_values(VALUES)
#@Overrides
def display_value(self, key, w):
if key == "vfolders":
# Even more special case
rids = [ ]
# Get list of folders that share this device
for r in self.config["folders"]:
for n in r["devices"]:
if n["deviceID"] == self.id and r["id"] not in rids:
rids.append(r["id"])
# Create CheckButtons
for folder in reversed(sorted(self.app.folders.values(), key=lambda x : x["id"])):
b = Gtk.CheckButton(folder["path"], False)
b.set_tooltip_text(folder["id"])
self["vfolders"].pack_start(b, False, False, 0)
b.set_active(folder["id"] in rids)
self["vfolders"].show_all()
else:
EditorDialog.display_value(self, key, w)
#@Overrides
def update_special_widgets(self, *a):
self["vdeviceID"].set_sensitive(self.is_new)
#@Overrides
def on_save_requested(self):
self.store_values(VALUES)
if self.is_new:
# Add new dict to configuration (edited dict is already there)
self.config["devices"].append(self.values)
# Post configuration back to daemon
self.post_config()
#@Overrides
def store_value(self, key, w):
if key == "vaddresses":
addresses = [
x.strip() if "://" in x or x.strip() == "dynamic" else "tcp://%s" % (x.strip(),)
for x in w.get_text().split(",") ]
self.set_value("addresses", ",".join(addresses))
elif key == "vfolders":
# Generate dict of { folder_id : bool } where bool is True if
# folder should be shared with this device
folders = {}
for b in self["vfolders"].get_children():
folders[b.get_tooltip_text()] = b.get_active()
# Go over all Folders/<folder>/Devices/<device> keys in config
# and set them as needed
nid = self.get_value("deviceID")
for r in self.config["folders"]:
rid = r["id"]
found = False
for n in r["devices"]:
if n["deviceID"] == nid:
if not rid in folders or not folders[rid]:
# Remove this /<device> key (unshare folder with device)
r["devices"].remove(n)
break
found = True
if (not found) and (rid in folders) and folders[rid]:
# Add new /<device> key (share folder with device)
r["devices"].append({
"addresses" : None,
"deviceID" : nid,
"name" : "",
"certName" : "",
"compression" : "metadata"
})
else:
EditorDialog.store_value(self, key, w)
#@Overrides
def on_saved(self):
self.close()
|