diff --git a/FAHControl b/FAHControl index 117525f5..a6c4f2e9 100755 --- a/FAHControl +++ b/FAHControl @@ -32,11 +32,11 @@ def set_proc_name(name): libc = cdll.LoadLibrary('libc.so.6') buff = create_string_buffer(len(name)+1) - buff.value = bytes(name,encoding="UTF8") + buff.value = name libc.prctl(15, byref(buff), 0, 0, 0) -if sys.platform.startswith('linux'): set_proc_name('FAHControl') +if sys.platform.startswith('linux'): set_proc_name(b'FAHControl') # If present, remove the Launch Services -psn_xxx_xxx argument if len(sys.argv) > 1 and sys.argv[1][:4] == '-psn': @@ -53,7 +53,7 @@ if options.exit: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(single_app_addr) - sock.send('EXIT') + sock.send(b'EXIT') if sock.recv(1024).strip() == 'OK': print ('Ok') except Exception as e: pass diff --git a/SConstruct b/SConstruct index d8f986c9..925ce243 100644 --- a/SConstruct +++ b/SConstruct @@ -3,8 +3,8 @@ import os env = Environment(ENV = os.environ) try: env.Tool('config', toolpath = [os.environ.get('CBANG_HOME')]) -except Exception, e: - raise Exception, 'CBANG_HOME not set?\n' + str(e) +except Exception as e: + raise Exception('CBANG_HOME not set?\n' + str(e)) env.CBLoadTools('packager run_distutils osx fah-client-version') env.CBAddVariables( @@ -14,7 +14,7 @@ conf = env.CBConfigure() # Version try: version = env.FAHClientVersion() -except Exception, e: +except Exception as e: print(e) version = '0.0.0' env.Replace(PACKAGE_VERSION = version) diff --git a/fah/Client.py b/fah/Client.py index 2cc12da6..911ad5ba 100644 --- a/fah/Client.py +++ b/fah/Client.py @@ -57,7 +57,7 @@ def __init__(self, app, name, address, port, password): # Option names names = list(app.client_option_widgets.keys()) - self.option_names = [name.replace('_', '-') for name in names] + self.option_names = list(map(lambda name: name.replace('_', '-'), names)) self.option_names.append('power') # Folding power # Init commands @@ -301,7 +301,7 @@ def process_error(self, app, data): self.name, self.address, self.port, data) # Only popup dialog once for each error - if not msg in self.error_messages: + if msg not in self.error_messages: self.error_messages.add(msg) app.error(msg) diff --git a/fah/ClientConfig.py b/fah/ClientConfig.py index a31bcb7b..1b5cc629 100644 --- a/fah/ClientConfig.py +++ b/fah/ClientConfig.py @@ -318,11 +318,11 @@ def update_info(self, app): category = category[1:] # Frame - #frame = Gtk.Frame('%s' % name) - frame = Gtk.Frame() - frame.name = name + frame = Gtk.Frame.new('%s' % name) frame.set_shadow_type(Gtk.ShadowType.ETCHED_IN) - vbox.pack_start(frame, False, True, 0) + frame.set_label_align(0.01, 0.5) + frame.get_label_widget().set_use_markup(True) + vbox.pack_start(frame, False, False, 0) # Alignment align = Gtk.Alignment.new(0, 0, 1, 1) @@ -649,7 +649,7 @@ def check_option(model, path, iter, data): # Removed options for name in self.options: - if not name in used: + if name not in used: options[name + '!'] = None return options diff --git a/fah/Connection.py b/fah/Connection.py index 57878bc2..9291ea53 100644 --- a/fah/Connection.py +++ b/fah/Connection.py @@ -102,11 +102,11 @@ def open(self): self.last_connect = time.time() self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.setblocking(0) + self.socket.setblocking(False) ready = select.select([self.socket], [self.socket], [], 10) if ready[0]: err = self.socket.connect_ex((self.address, self.port)) - if err != 0 and err != 115 and not err in [ + if err != 0 and err != 115 and err not in [ errno.EINPROGRESS, errno.EWOULDBLOCK, WSAEWOULDBLOCK]: self.fail_reason = 'connect' raise Exception('Connection failed: ' + errno.errorcode[err]) @@ -160,14 +160,11 @@ def read_some(self): self.connection_lost() return 0 - except socket.error as xxx_todo_changeme: + except socket.error as err: # Error codes for nothing to read - (err, msg) = xxx_todo_changeme.args - # Error codes for nothing to read - if err not in [errno.EAGAIN, errno.EWOULDBLOCK, WSAEWOULDBLOCK]: - if bytesRead: - return bytesRead - self.connection_error(err, msg) + if err.errno not in [errno.EAGAIN, errno.EWOULDBLOCK, WSAEWOULDBLOCK]: + if bytesRead: return bytesRead + self.connection_error(err.errno, err.strerror) raise return bytesRead @@ -189,14 +186,11 @@ def write_some(self): self.connection_lost() return 0 - except socket.error as xxx_todo_changeme1: - # Error codes for write buffer full - (err, msg) = xxx_todo_changeme1.args + except socket.error as err: # Error codes for write buffer full - if err not in [errno.EAGAIN, errno.EWOULDBLOCK, WSAEWOULDBLOCK]: - if bytesWritten: - return bytesWritten - self.connection_error(err, msg) + if err.errno not in [errno.EAGAIN, errno.EWOULDBLOCK, WSAEWOULDBLOCK]: + if bytesWritten: return bytesWritten + self.connection_error(err.errno, err.strerror) raise return bytesWritten diff --git a/fah/FAHControl.glade b/fah/FAHControl.glade index 16b38ba8..3048104e 100644 --- a/fah/FAHControl.glade +++ b/fah/FAHControl.glade @@ -1,5 +1,5 @@ - + @@ -528,7 +528,7 @@ True False - 0 + 0.01 True @@ -695,7 +695,7 @@ True False - 0 + 0.01 none @@ -792,7 +792,7 @@ True False - 0 + 0.01 True @@ -871,7 +871,7 @@ True False - 0 + 0.05 True @@ -976,7 +976,7 @@ 160 True False - 0 + 0.1 True @@ -1031,6 +1031,7 @@ True True + 3 vertical 100 True @@ -1038,7 +1039,7 @@ True False - 0 + 0.02 True @@ -1130,7 +1131,7 @@ True False - 0 + 0.02 True @@ -1252,7 +1253,8 @@ True False - 0 + 3 + 0.01 True @@ -1891,7 +1893,8 @@ True False - 0 + 5 + 0.01 True @@ -2036,6 +2039,7 @@ True True + 5 etched-in @@ -2059,6 +2063,7 @@ True False + 5 2 @@ -2238,6 +2243,7 @@ True False + vertical 4 @@ -2295,6 +2301,19 @@ 2 + + + True + False + gtk-missing-image + 6 + + + False + True + 3 + + 1 @@ -2384,7 +2403,7 @@ True False - 0 + 0.01 True @@ -2657,7 +2676,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -2762,7 +2781,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -2927,7 +2946,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -2957,7 +2976,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -2999,7 +3018,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -3063,7 +3082,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -3208,7 +3227,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -3310,7 +3329,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -3337,7 +3356,7 @@ Would you like to configure your identity now? 580 True False - 0 + 0.01 True @@ -3416,7 +3435,7 @@ Would you like to configure your identity now? 580 True False - 0 + 0.01 True @@ -3498,7 +3517,7 @@ Would you like to configure your identity now? 580 True False - 0 + 0.01 True @@ -3756,7 +3775,7 @@ Would you like to configure your identity now? True False - 0 + 0.01 True @@ -3799,7 +3818,7 @@ Folding slots can be one of two types, CPU or GPU. Representing the different t True False - 0 + 0.01 True @@ -4006,7 +4025,7 @@ Folding slots can be one of two types, CPU or GPU. Representing the different t True False - 0 + 0.01 True @@ -4054,7 +4073,7 @@ Warning, changes you make here may render your client inaccessible even from the True False - 0 + 0.01 True @@ -4220,7 +4239,7 @@ Warning, changes you make here may render your client inaccessible even from the True False - 0 + 0.01 True @@ -4309,7 +4328,7 @@ Warning, changes you make here may render your client inaccessible even from the True False - 0 + 0.01 True @@ -4440,7 +4459,7 @@ The following range specification matches all IP address: True False - 0 + 0.01 True @@ -4601,7 +4620,7 @@ Addresses listed here also need to be listed above to allow access. True False - 0 + 0.01 True @@ -4651,7 +4670,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -4784,7 +4803,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -5035,7 +5054,7 @@ Addresses listed here also need to be listed above to allow access. True False - 0 + 0.01 True @@ -5062,7 +5081,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -5158,7 +5177,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -5249,7 +5268,7 @@ Addresses listed here also need to be listed above to allow access. 580 False - 0 + 0.01 True @@ -5316,7 +5335,7 @@ Addresses listed here also need to be listed above to allow access. 580 False - 0 + 0.01 True @@ -5385,7 +5404,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -5452,7 +5471,7 @@ Addresses listed here also need to be listed above to allow access. 580 False - 0 + 0.01 True @@ -5514,7 +5533,7 @@ Addresses listed here also need to be listed above to allow access. 580 True False - 0 + 0.01 True @@ -5619,7 +5638,7 @@ Addresses listed here also need to be listed above to allow access. True False - 0 + 0.01 True @@ -5666,7 +5685,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 True @@ -5819,7 +5838,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 True @@ -6098,7 +6117,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 none @@ -6124,7 +6143,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 in @@ -6172,7 +6191,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 True @@ -6284,7 +6303,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 in @@ -6333,7 +6352,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 True @@ -6421,7 +6440,7 @@ Some of these options may require manually restarting the client to take effect. True False - 0 + 0.01 True @@ -6567,7 +6586,7 @@ WARNING, changing these values can make your GPU folding slot fail. 150 True False - 0 + 0.01 True @@ -6981,6 +7000,7 @@ Folding slots can be one of three types, Uniprocessor, SMP or GPU. Representing True False + vertical 2 @@ -7029,7 +7049,7 @@ Folding slots can be one of three types, Uniprocessor, SMP or GPU. Representing True False - 0 + 0.01 True @@ -7256,7 +7276,7 @@ Folding slots can be one of three types, Uniprocessor, SMP or GPU. Representing True False - 0 + 0.01 True @@ -7384,7 +7404,7 @@ Folding slots can be one of three types, Uniprocessor, SMP or GPU. Representing True False - 0 + 0.01 True diff --git a/fah/FAHControl.py b/fah/FAHControl.py index a0d0097a..d0417883 100644 --- a/fah/FAHControl.py +++ b/fah/FAHControl.py @@ -22,6 +22,7 @@ from fah.util import * from fah.db import * from fah import * +from fah.Version import version from .wraplabel import WrapLabel import subprocess import shlex @@ -36,22 +37,18 @@ import urllib.parse import urllib.error +import gi + +gi.require_version("Gtk", "3.0") from gi.repository import Gtk from gi.repository import GLib from gi.repository import Gdk from gi.repository.GdkPixbuf import Pixbuf, InterpType -import gi -gi.require_version("Gtk", "3.0") # OSX integration if sys.platform == 'darwin': - try: - from gtk_osxapplication import * - except: - import gtkosx_application - from gtkosx_application import Application as OSXApplication - from gtkosx_application import gtkosx_application_get_resource_path \ - as quartz_application_get_resource_path + gi.require_version('GtkosxApplication', '1.0') + from gi.repository import GtkosxApplication def set_tree_view_font(widget, font): @@ -102,8 +99,8 @@ def applicationShouldHandleReopen_hasVisibleWindows_(self, app, flag): try: import objc cls = objc.lookUpClass('GtkApplicationDelegate') - sig1 = '%s%s%s%s%s' % (objc._C_NSBOOL, objc._C_ID, objc._C_SEL, - objc._C_ID, objc._C_NSBOOL) + sig1 = b'%s%s%s%s%s' % (objc._C_NSBOOL, objc._C_ID, objc._C_SEL, + objc._C_ID, objc._C_NSBOOL) objc.classAddMethods(cls, [ objc.selector( applicationShouldHandleReopen_hasVisibleWindows_, @@ -187,10 +184,9 @@ def __init__(self, glade='FAHControl.glade'): # OSX integration if sys.platform == 'darwin': - self.osx_app = OSXApplication() + self.osx_app = GtkosxApplication.Application() self.osx_app.set_use_quartz_accelerators(True) self.osx_version = osx_version() - self.is_old_gtk = Gtk.gtk_version < (2, 24) osx_add_GtkApplicationDelegate_methods() # Style @@ -198,7 +194,7 @@ def __init__(self, glade='FAHControl.glade'): self.system_theme = settings.get_property('gtk-theme-name') if sys.platform == 'darwin': # Load standard key bindings for Mac and disable mnemonics - resources = quartz_application_get_resource_path() + resources = self.osx_app.get_resource_path() rcfile = os.path.join(resources, 'themes/Mac/gtk-2.0-key/gtkrc') if os.path.exists(rcfile): Gtk.rc_parse(rcfile) @@ -208,14 +204,7 @@ def __init__(self, glade='FAHControl.glade'): self.mono_font = Pango.FontDescription('Monospace') # Default icon - try: - self.window.set_default_icon('FAHControl.ico') - except: - try: - self.window.set_default_icon_from_file(os.path.dirname( - os.path.abspath(__file__)) + '/../images/FAHControl.ico') - except: - pass + self.window.set_default_icon_from_file(os.path.dirname(os.path.abspath(__file__)) + '/../images/FAHControl.ico') # Filter glade if len(glade) < 1024: @@ -306,11 +295,11 @@ def __init__(self, glade='FAHControl.glade'): win.connect('configure_event', self.store_dimensions, name) # About Dialog + icon = builder.get_object('about_icon',) + icon.set_from_file(os.path.dirname(os.path.abspath(__file__)) + '/../images/FAHControl.ico') + about_version = builder.get_object('about_version') - try: - about_version.set_markup('Version: %s' % version) - except: - pass + about_version.set_markup('Version: %s' % version) # Preferences self.theme_list = self.load_themes() @@ -434,20 +423,13 @@ def __init__(self, glade='FAHControl.glade'): if sys.platform == 'darwin': # Setup dock menu self.osx_menu = builder.get_object('osx_tray_menu') - if self.is_old_gtk: - self.osx_app.set_dock_menu(self.osx_menu) - else: - self.osx_create_dock_menu(self.osx_menu) + self.osx_create_dock_menu(self.osx_menu) # Create application menu self.osx_menubar = Gtk.MenuBar() self.osx_menubar.show_all() self.osx_app.set_menu_bar(self.osx_menubar) - if self.is_old_gtk: - self.osx_group = self.osx_app.add_app_menu_group() - self.osx_menu.foreach(self.osx_add_to_menu) - else: - self.osx_create_app_menu(self.osx_menu) + self.osx_create_app_menu(self.osx_menu) # Hide some widgets in OSX for name in ['ui_pref_frame', 'theme_pref', 'theme_label']: @@ -455,8 +437,6 @@ def __init__(self, glade='FAHControl.glade'): widget.set_property('visible', False) if self.osx_version >= (10, 7): - # remove broken window resize grip - self.status_bar.set_property('has-resize-grip', False) self.time_label.set_property('xpad', 6) else: self.time_label.set_property('xpad', 2) @@ -541,20 +521,17 @@ def run(self): self.osx_app.ready() - if self.osx_version >= (10, 7) and self.osx_version < (10, 9): - self.osx_window_focus_workaround() - try: # add cmd-w and cmd-m to window # cmd-w would need to be same as cancel for dialogs ag = Gtk.AccelGroup() self.window_accel_group = ag key, mod = Gtk.accelerator_parse("w") - ag.connect_group(key, mod, Gtk.AccelFlags.VISIBLE, - osx_accel_window_close) + ag.connect(key, mod, Gtk.AccelFlags.VISIBLE, + osx_accel_window_close) key, mod = Gtk.accelerator_parse("m") - ag.connect_group(key, mod, Gtk.AccelFlags.VISIBLE, - osx_accel_window_minimize) + ag.connect(key, mod, Gtk.AccelFlags.VISIBLE, + osx_accel_window_minimize) self.window.add_accel_group(ag) except Exception as e: print(e) @@ -608,18 +585,6 @@ def activate_item(widget, target): # retain menu, or it won't work self.osx_dock_menu = menu - def osx_window_focus_workaround(self): - # osx 10.7+, part of Trac #793, not resolved by gtk 2.24.10 - # only thing that works is clicking FAHControl icon in Dock - # this is the equivalent - # must be backgrounded so app can process reopen event - # and not deadlock waiting for osascript - cmd = ['/usr/bin/osascript', '-e', 'tell app "FAHControl" to reopen'] - try: - subprocess.Popen(cmd) - except Exception as e: - print(e, ':', ' '.join(cmd)) - def connect_option_cell(self, name, model, col): cell = self.builder.get_object(name) cell.connect('edited', self.on_option_edit, model, col) @@ -1095,9 +1060,9 @@ def save_client_config(self, client): return True - except Exception as exc: + except Exception as err: self.set_status('Save Failed') - self.error(exc) + self.error(err) return False def check_duplicate_client_name(self, name): @@ -1481,7 +1446,7 @@ def on_client_add_button_clicked(self, widget, data=None): # Make client name for i in range(sys.maxsize): name = 'client%d' % i - if not name in self.clients: + if name not in self.clients: break self.client_entries['name'].set_text(name) diff --git a/fah/SlotConfig.py b/fah/SlotConfig.py index 354f84b7..109e4e61 100644 --- a/fah/SlotConfig.py +++ b/fah/SlotConfig.py @@ -117,5 +117,5 @@ def load_dialog(self, app): # Options app.slot_option_list.clear() for name, value in self.options.items(): - if not name in used: + if name not in used: app.slot_option_list.append((name, str(value))) diff --git a/fah/db/Table.py b/fah/db/Table.py index 1679e256..05f42556 100644 --- a/fah/db/Table.py +++ b/fah/db/Table.py @@ -59,7 +59,7 @@ def insert(self, db, **kwargs): # Error checking if len(cols) != len(kwargs): col_names = set(map(Column.get_name, cols)) - missing = [kw for kw in list(kwargs.keys()) if not kw in col_names] + missing = [kw for kw in list(kwargs.keys()) if kw not in col_names] raise Exception('Table %s does not have column(s) %s' % (self.name, ', '.join(missing))) diff --git a/fah/util/PasswordValidator.py b/fah/util/PasswordValidator.py index f8a72408..3fce7145 100644 --- a/fah/util/PasswordValidator.py +++ b/fah/util/PasswordValidator.py @@ -22,7 +22,6 @@ import gi gi.require_version('Gtk', '3.0') - from gi.repository import Gtk from fah.util.EntryValidator import EntryValidator diff --git a/fah/util/SingleApp.py b/fah/util/SingleApp.py index bd93bc50..5a28a546 100644 --- a/fah/util/SingleApp.py +++ b/fah/util/SingleApp.py @@ -69,7 +69,7 @@ def check_for_instance(self): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(single_app_addr) - sock.send('PING') + sock.send(b'PING') if sock.recv(1024).strip() == 'OK': print ('Already running') sys.exit(1) diff --git a/setup.py b/setup.py index 9f4e17e4..4627c038 100644 --- a/setup.py +++ b/setup.py @@ -127,6 +127,7 @@ keywords='protein, molecular dynamics, simulation', url='https://foldingathome.org/', package_data={'fah': ['*.glade']}, + python_requires='>=3.5', **extra_opts) if sys.platform == 'darwin':