From 93ef1a1a8cc29ce00839b109c08c18a4bedd1b18 Mon Sep 17 00:00:00 2001 From: gpatel-fr <44170243+gpatel-fr@users.noreply.github.com> Date: Wed, 26 Apr 2023 11:15:47 +0200 Subject: [PATCH] updates rumps to python3, add icon normal-warning, set rumps as default --- .../Duplicati.GUI.TrayIcon.csproj | 3 ++ .../OSX Icons/normal-warning.png | Bin 0 -> 948 bytes .../OSXTrayHost/osx-trayicon-rumps.py | 40 +++++++++--------- .../GUI/Duplicati.GUI.TrayIcon/Program.cs | 2 +- .../GUI/Duplicati.GUI.TrayIcon/RumpsRunner.cs | 5 ++- thirdparty/rumps/rumps.py | 34 +++++++-------- 6 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 Duplicati/GUI/Duplicati.GUI.TrayIcon/OSX Icons/normal-warning.png diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj index 0913e5d01..5dbd5d4d8 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Duplicati.GUI.TrayIcon.csproj @@ -158,6 +158,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSX Icons/normal-warning.png b/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSX Icons/normal-warning.png new file mode 100644 index 0000000000000000000000000000000000000000..882a31c5c754c8b254b0b77f28fce4c9184b126e GIT binary patch literal 948 zcmeAS@N?(olHy`uVBq!ia0y~yU{C>J4mJh`hKCF@W-u@?a29w(7Beu2se&-0XOPMV z1_lPn64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq!<{O9X(wfLn2zw&hXEO zbrm^QAHOjmr{nFZH^C*U`VUr>C2#x@6PYE}r0`CuWbv{^N4;1VF8$vz<&svRXn=T< z`BC34#)Rpjt^Yb3fk#GFSHaoAc{GOTSk-NSf zmON{ip5Okoe9xx5XUiV3t|_?MeIW9I?}J#+^;d4XpF8u`v&qQbysOiK^H0`qwF0Ic z6AaWJzq`UU$z)pgI+KmZE?YQRDCYcUdo$^a-{C8a_+RCz`ESt= z+n3DGy}$mkRH&Xc^Phy@aW@ydWj~PWv}FC!X{?@Ab05s>Ze4i0^_%L0UWt|Sdl$Tz zcKU$&HuefcPK+x9@+gQb%;`ZoqoDtr1%jcre)Q=jBt-Y#zGxiJ0h8QEe{r%x8?)q$5Bos9M{|A|i8?$zO1X~VRs!r1S| zkJSgV4~R?d=Quv~s@3Zjg|fqC`r8-hurmj4tmo0_K2YubtBfhRb)V;h$3JRse(Pz_ zZ`{6kM&#}CZlA)3@fm>&rYe5&35r`#n^5h0VC#+xrMJ_iPdt;T<-DyvWka?=T;#Ub z(xsbo*591Rc<$qtx|>Eh=fj?ETH^ZX@5(j3D!Q(_w`b*8wOp1vq`zXzj8DdMg^@uwSlvBccAp;tV#(#+3?2Mn(tQclr~O% z=OJ{(Xs6jiqrY2(SUjJ)Po5yRVZ+VIl0sWzH@yAV{Eg)w$FpM#eNX8zFfcH9y85}S Ib4q9e00ok{QUCw| literal 0 HcmV?d00001 diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py b/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py index 3f52696df..290985070 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/OSXTrayHost/osx-trayicon-rumps.py @@ -41,7 +41,7 @@ def transform_app_type(toForeground): def item_clicked(sender): for k in lookup: if lookup[k].title == sender.title: - print "click:%s" % k + print("click:%s" % k) sys.stdout.flush() @@ -49,7 +49,7 @@ def parsemenus(cfg): menuitems = [] for n in cfg["Menus"]: mn = rumps.MenuItem(n["Text"]) - if n.has_key("Enabled") and not n["Enabled"]: + if "Enabled" in n and not n["Enabled"]: mn.set_callback(None) else: mn.set_callback(item_clicked) @@ -69,7 +69,7 @@ def get_input(): if line == '': continue - print "info:Read %s" % line + print("info:Read %s" % line) sys.stdout.flush() cfg = None try: @@ -78,27 +78,27 @@ def get_input(): pass if cfg == None: - print "info:Unable to parse line" + print("info:Unable to parse line") sys.stdout.flush() continue - if cfg.has_key("Action"): - print "info:Running %s" % cfg["Action"] + if "Action" in cfg: + print("info:Running %s" % cfg["Action"]) sys.stdout.flush() if cfg["Action"] == "setmenu": menu = cfg["Menu"] - if lookup.has_key(menu["Key"]): + if menu["Key"] in lookup: lookup[menu["Key"]].title = menu["Text"] - if menu.has_key("Enabled") and not menu["Enabled"]: + if "Enabled" in menu and not menu["Enabled"]: lookup[menu["Key"]].set_callback(None) else: lookup[menu["Key"]].set_callback(item_clicked) app.menu.update([]) else: - print "warn:Key not found %s" % cfg["Action"] + print("warn:Key not found %s" % cfg["Action"]) sys.stdout.flush() @@ -106,7 +106,7 @@ def get_input(): elif cfg["Action"] == "setmenus": app.menu.clear() app.menu = parsemenus(cfg) - print "info:Updated menus" + print("info:Updated menus") sys.stdout.flush() elif cfg["Action"] == "seticon": @@ -119,11 +119,11 @@ def get_input(): img.setTemplate_(True) app.icon = img - print "info:Image updated" + print("info:Image updated") sys.stdout.flush() except: - print "warn:Failed to set image" + print("warn:Failed to set image") sys.stdout.flush() elif cfg["Action"] == "setappicon": @@ -136,11 +136,11 @@ def get_input(): #img.setSize_((21, 21)) NSApplication.sharedApplication().setApplicationIconImage_(img) - print "info:AppImage updated" + print("info:AppImage updated") sys.stdout.flush() except: - print "warn:Failed to set image" + print("warn:Failed to set image") sys.stdout.flush() elif cfg["Action"] == "shutdown": @@ -159,18 +159,18 @@ def get_input(): playSound = True image = None - if cfg.has_key("SubTitle"): + if "SubTitle" in cfg: subtitle = cfg["SubTitle"] - if cfg.has_key("PlaySound"): + if "PlaySound" in cfg: playSound = cfg["PlaySound"] - if cfg.has_key("Image"): + if "Image" in cfg: try: raw = base64.b64decode(cfg["Image"]) data = NSData.dataWithBytes_length_(raw, len(raw)) image = NSImage.alloc().initWithData_(data) except: - print "warn:Failed to decode image" + print("warn:Failed to decode image") sys.stdout.flush() rumps.notification(cfg["Title"], subtitle, cfg["Message"], sound=playSound, image=image) @@ -182,10 +182,10 @@ def get_input(): pass rumps.quit_application() - print "info:Shutdown" + print("info:Shutdown") sys.stdout.flush() - print "info:Stdin close" + print("info:Stdin close") sys.stdout.flush() sys.stdin.close() diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs index 378aeb0e0..8551142f2 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/Program.cs @@ -44,7 +44,7 @@ namespace Duplicati.GUI.TrayIcon private static string GetDefaultToolKit() { if (Platform.IsClientOSX) - return TOOLKIT_COCOA; + return TOOLKIT_RUMPS; #if __WindowsGTK__ || ENABLE_GTK if (Platform.IsClientPosix) diff --git a/Duplicati/GUI/Duplicati.GUI.TrayIcon/RumpsRunner.cs b/Duplicati/GUI/Duplicati.GUI.TrayIcon/RumpsRunner.cs index 0d8a10fd9..625a67797 100644 --- a/Duplicati/GUI/Duplicati.GUI.TrayIcon/RumpsRunner.cs +++ b/Duplicati/GUI/Duplicati.GUI.TrayIcon/RumpsRunner.cs @@ -92,14 +92,15 @@ namespace Duplicati.GUI.TrayIcon private static readonly string ICON_NORMAL = ICON_PATH + "normal.png"; private static readonly string ICON_PAUSED = ICON_PATH + "normal-pause.png"; private static readonly string ICON_RUNNING = ICON_PATH + "normal-running.png"; - private static readonly string ICON_WARNING = ICON_PATH + "normal-error.png"; // TODO: create a normal-warning.png, for now use normal-error.png + private static readonly string ICON_WARNING = ICON_PATH + "normal-warning.png"; private static readonly string ICON_ERROR = ICON_PATH + "normal-error.png"; private readonly Dictionary m_images = new Dictionary(); private System.Diagnostics.Process m_rumpsProcess; - private static readonly string RUMPS_PYTHON = string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("RUMPS_PYTHON")) ? "/usr/bin/python2.7" : Environment.GetEnvironmentVariable("RUMPS_PYTHON"); + private static readonly string SYSTEM_PYTHON = System.IO.Directory.Exists("/usr/bin/python2.7") ? "/usr/bin/python2.7" : "/usr/bin/python3"; + private static readonly string RUMPS_PYTHON = string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("RUMPS_PYTHON")) ? SYSTEM_PYTHON : Environment.GetEnvironmentVariable("RUMPS_PYTHON"); private static readonly string SCRIPT_PATH = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "OSXTrayHost", "osx-trayicon-rumps.py"); private IsolatedChannelScope m_scope; diff --git a/thirdparty/rumps/rumps.py b/thirdparty/rumps/rumps.py index a1ff64c62..c58d47972 100644 --- a/thirdparty/rumps/rumps.py +++ b/thirdparty/rumps/rumps.py @@ -82,11 +82,11 @@ def alert(title=None, message='', ok=None, cancel=None): created. :return: a number representing the button pressed. The "ok" button is ``1`` and "cancel" is ``0``. """ - message = unicode(message) + message = str(message) if title is not None: - title = unicode(title) + title = str(title) _require_string_or_none(ok) - if not isinstance(cancel, basestring): + if not isinstance(cancel, str): cancel = 'Cancel' if cancel else None alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_( title, ok, cancel, None, message) @@ -176,13 +176,13 @@ def _nsimage_from_file(filename, dimensions=None): def _require_string(*objs): for obj in objs: - if not isinstance(obj, basestring): + if not isinstance(obj, str): raise TypeError('a string is required but given {0}, a {1}'.format(obj, type(obj).__name__)) def _require_string_or_none(*objs): for obj in objs: - if not(obj is None or isinstance(obj, basestring)): + if not(obj is None or isinstance(obj, str)): raise TypeError('a string or None is required but given {0}, a {1}'.format(obj, type(obj).__name__)) @@ -361,14 +361,14 @@ class Menu(ListDict): menu.add(iterable) return - for n, ele in enumerate(iterable.iteritems() if isinstance(iterable, Mapping) else iterable): + for n, ele in enumerate(iter(iterable.items()) if isinstance(iterable, Mapping) else iterable): # for mappings we recurse but don't drop down a level in the menu if not isinstance(ele, MenuItem) and isinstance(ele, Mapping): parse_menu(ele, menu, depth) # any iterables other than strings and MenuItems - elif not isinstance(ele, (basestring, MenuItem)) and isinstance(ele, Iterable): + elif not isinstance(ele, (str, MenuItem)) and isinstance(ele, Iterable): try: menuitem, submenu = ele except TypeError: @@ -484,7 +484,7 @@ class MenuItem(Menu): def __init__(self, title, callback=None, key=None, icon=None, dimensions=None): if isinstance(title, MenuItem): # don't initialize already existing instances return - self._menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(unicode(title), None, '') + self._menuitem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(str(title), None, '') self._menuitem.setTarget_(NSApp) self._menu = self._icon = None self.set_callback(callback, key) @@ -498,7 +498,7 @@ class MenuItem(Menu): super(MenuItem, self).__setitem__(key, value) def __repr__(self): - return '<{0}: [{1} -> {2}; callback: {3}]>'.format(type(self).__name__, repr(self.title), map(str, self), + return '<{0}: [{1} -> {2}; callback: {3}]>'.format(type(self).__name__, repr(self.title), list(map(str, self)), repr(self.callback)) @property @@ -510,7 +510,7 @@ class MenuItem(Menu): @title.setter def title(self, new_title): - new_title = unicode(new_title) + new_title = str(new_title) self._menuitem.setTitle_(new_title) @property @@ -707,14 +707,14 @@ class Window(object): """ def __init__(self, message='', title='', default_text='', ok=None, cancel=None, dimensions=(320, 160)): - message = unicode(message) - title = unicode(title) + message = str(message) + title = str(title) self._cancel = bool(cancel) self._icon = None _require_string_or_none(ok) - if not isinstance(cancel, basestring): + if not isinstance(cancel, str): cancel = 'Cancel' if cancel else None self._alert = NSAlert.alertWithMessageText_defaultButton_alternateButton_otherButton_informativeTextWithFormat_( @@ -736,7 +736,7 @@ class Window(object): @title.setter def title(self, new_title): - new_title = unicode(new_title) + new_title = str(new_title) self._alert.setMessageText_(new_title) @property @@ -748,7 +748,7 @@ class Window(object): @message.setter def message(self, new_message): - new_message = unicode(new_message) + new_message = str(new_message) self._alert.setInformativeText_(new_message) @property @@ -763,7 +763,7 @@ class Window(object): @default_text.setter def default_text(self, new_text): - new_text = unicode(new_text) + new_text = str(new_text) self._default_text = new_text self._textfield.setStringValue_(new_text) @@ -805,7 +805,7 @@ class Window(object): """ if iterable is None: return - if isinstance(iterable, basestring): + if isinstance(iterable, str): self.add_button(iterable) else: for ele in iterable: