attempt to fix gtk import
This commit is contained in:
parent
90abed89c1
commit
2fc888c924
@ -308,12 +308,12 @@ class ClientConfig:
|
||||
port.remove(child)
|
||||
|
||||
# Alignment
|
||||
align = gtk.Alignment(0, 0, 1, 1)
|
||||
align = Gtk.Alignment(0, 0, 1, 1)
|
||||
align.set_padding(4, 4, 4, 4)
|
||||
port.add(align)
|
||||
|
||||
# Vertical box
|
||||
vbox = gtk.VBox()
|
||||
vbox = Gtk.VBox()
|
||||
align.add(vbox)
|
||||
|
||||
for category in self.info:
|
||||
@ -321,18 +321,18 @@ class ClientConfig:
|
||||
category = category[1:]
|
||||
|
||||
# Frame
|
||||
frame = gtk.Frame('<b>%s</b>' % name)
|
||||
frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
|
||||
frame = Gtk.Frame('<b>%s</b>' % name)
|
||||
frame.set_shadow_type(Gtk.SHADOW_ETCHED_IN)
|
||||
frame.get_label_widget().set_use_markup(True)
|
||||
vbox.pack_start(frame, False)
|
||||
|
||||
# Alignment
|
||||
align = gtk.Alignment(0, 0, 1, 1)
|
||||
align = Gtk.Alignment(0, 0, 1, 1)
|
||||
align.set_padding(0, 0, 12, 0)
|
||||
frame.add(align)
|
||||
|
||||
# Table
|
||||
table = gtk.Table(len(category), 2)
|
||||
table = Gtk.Table(len(category), 2)
|
||||
table.set_col_spacing(0, 5)
|
||||
align.add(table)
|
||||
|
||||
@ -342,23 +342,23 @@ class ClientConfig:
|
||||
continue
|
||||
|
||||
# Name
|
||||
label = gtk.Label('<b>%s</b>' % name)
|
||||
label = Gtk.Label('<b>%s</b>' % name)
|
||||
label.set_use_markup(True)
|
||||
label.set_alignment(1, 0.5)
|
||||
table.attach(label, 0, 1, row, row + 1, gtk.FILL, gtk.FILL)
|
||||
table.attach(label, 0, 1, row, row + 1, Gtk.FILL, Gtk.FILL)
|
||||
|
||||
# Value
|
||||
if value.startswith('http://'):
|
||||
label = gtk.LinkButton(value, value)
|
||||
label.set_relief(gtk.RELIEF_NONE)
|
||||
label = Gtk.LinkButton(value, value)
|
||||
label.set_relief(Gtk.RELIEF_NONE)
|
||||
label.set_property('can-focus', False)
|
||||
|
||||
else:
|
||||
label = gtk.Label(value)
|
||||
label = Gtk.Label(value)
|
||||
|
||||
label.set_alignment(0, 0.5)
|
||||
label.modify_font(app.mono_font)
|
||||
table.attach(label, 1, 2, row, row + 1, yoptions=gtk.FILL)
|
||||
table.attach(label, 1, 2, row, row + 1, yoptions=Gtk.FILL)
|
||||
|
||||
row += 1
|
||||
|
||||
|
@ -56,7 +56,7 @@ if sys.platform == 'darwin':
|
||||
|
||||
def set_tree_view_font(widget, font):
|
||||
for widget in iterate_container(widget):
|
||||
if isinstance(widget, gtk.TreeView):
|
||||
if isinstance(widget, Gtk.TreeView):
|
||||
widget.modify_font(font)
|
||||
|
||||
|
||||
@ -193,10 +193,10 @@ class FAHControl(SingleAppServer):
|
||||
osx_add_GtkApplicationDelegate_methods()
|
||||
|
||||
# URI hook
|
||||
gtk.link_button_set_uri_hook(self.on_uri_hook, None)
|
||||
Gtk.link_button_set_uri_hook(self.on_uri_hook, None)
|
||||
|
||||
# Style
|
||||
settings = gtk.settings_get_default()
|
||||
settings = Gtk.settings_get_default()
|
||||
self.system_theme = settings.get_property('gtk-theme-name')
|
||||
if sys.platform == 'darwin':
|
||||
# Load standard key bindings for Mac and disable mnemonics
|
||||
@ -206,12 +206,12 @@ class FAHControl(SingleAppServer):
|
||||
gtk.rc_parse(rcfile)
|
||||
rcfile = os.path.join(os.path.expanduser("~"), '.FAHClient/gtkrc')
|
||||
if os.path.exists(rcfile):
|
||||
gtk.rc_parse(rcfile)
|
||||
Gtk.rc_parse(rcfile)
|
||||
self.mono_font = pango.FontDescription('Monospace')
|
||||
small_font = pango.FontDescription('Sans 8')
|
||||
|
||||
# Default icon
|
||||
gtk.window_set_default_icon(get_icon('small'))
|
||||
Gtk.window_set_default_icon(get_icon('small'))
|
||||
|
||||
# Filter glade
|
||||
if len(glade) < 1024:
|
||||
@ -226,7 +226,7 @@ class FAHControl(SingleAppServer):
|
||||
glade)[0]
|
||||
|
||||
# Build GUI
|
||||
self.builder = builder = gtk.Builder()
|
||||
self.builder = builder = Gtk.Builder()
|
||||
try:
|
||||
builder.add_from_string(glade)
|
||||
except:
|
||||
@ -340,9 +340,9 @@ class FAHControl(SingleAppServer):
|
||||
self.connect_option_view('slot_')
|
||||
self.core_option_tree = builder.get_object('core_option_tree_view')
|
||||
self.core_option_list = builder.get_object('core_option_list')
|
||||
self.option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.slot_option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.core_option_tree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
|
||||
self.option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||
self.slot_option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||
self.core_option_tree.get_selection().set_mode(Gtk.SELECTION_MULTIPLE)
|
||||
|
||||
# Option dialog
|
||||
self.option_name_entry = builder.get_object('option_name_entry')
|
||||
@ -357,7 +357,7 @@ class FAHControl(SingleAppServer):
|
||||
for i in range(len(self.folding_power_levels)):
|
||||
level = self.folding_power_levels[i]
|
||||
markup = '<span font_size="small" weight="bold">%s</span>' % level
|
||||
self.folding_power.add_mark(i, gtk.POS_BOTTOM, markup)
|
||||
self.folding_power.add_mark(i, Gtk.POS_BOTTOM, markup)
|
||||
|
||||
# User info
|
||||
self.donor_info = builder.get_object('donor_info')
|
||||
@ -381,7 +381,7 @@ class FAHControl(SingleAppServer):
|
||||
|
||||
# Slot lists
|
||||
self.slot_status_tree = builder.get_object('slot_status_tree_view')
|
||||
self.slot_status_tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
|
||||
self.slot_status_tree.get_selection().set_mode(Gtk.SELECTION_SINGLE)
|
||||
self.slot_status_list = builder.get_object('slot_status_list')
|
||||
self.slot_tree = builder.get_object('slot_tree_view')
|
||||
self.slot_list = builder.get_object('slot_list')
|
||||
@ -553,32 +553,32 @@ class FAHControl(SingleAppServer):
|
||||
try:
|
||||
# add cmd-w and cmd-m to window
|
||||
# cmd-w would need to be same as cancel for dialogs
|
||||
ag = gtk.AccelGroup()
|
||||
ag = Gtk.AccelGroup()
|
||||
self.window_accel_group = ag
|
||||
key, mod = gtk.accelerator_parse("<meta>w")
|
||||
ag.connect_group(key, mod, gtk.ACCEL_VISIBLE,
|
||||
key, mod = Gtk.accelerator_parse("<meta>w")
|
||||
ag.connect_group(key, mod, Gtk.ACCEL_VISIBLE,
|
||||
osx_accel_window_close)
|
||||
key, mod = gtk.accelerator_parse("<meta>m")
|
||||
ag.connect_group(key, mod, gtk.ACCEL_VISIBLE,
|
||||
key, mod = Gtk.accelerator_parse("<meta>m")
|
||||
ag.connect_group(key, mod, Gtk.ACCEL_VISIBLE,
|
||||
osx_accel_window_minimize)
|
||||
self.window.add_accel_group(ag)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
gtk.main()
|
||||
Gtk.main()
|
||||
|
||||
# Util
|
||||
def osx_add_to_menu(self, widget):
|
||||
if isinstance(widget, gtk.SeparatorMenuItem):
|
||||
if isinstance(widget, Gtk.SeparatorMenuItem):
|
||||
self.osx_group = self.osx_app.add_app_menu_group()
|
||||
|
||||
elif isinstance(widget, gtk.MenuItem):
|
||||
elif isinstance(widget, Gtk.MenuItem):
|
||||
name = widget.child.get_text()
|
||||
|
||||
def activate_item(widget, target):
|
||||
target.emit('activate')
|
||||
|
||||
item = gtk.MenuItem(name)
|
||||
item = Gtk.MenuItem(name)
|
||||
item.show()
|
||||
item.connect('activate', activate_item, widget)
|
||||
self.osx_app.add_app_menu_item(self.osx_group, item)
|
||||
@ -586,26 +586,26 @@ class FAHControl(SingleAppServer):
|
||||
def osx_create_app_menu(self, widgets):
|
||||
i = 0
|
||||
for widget in widgets:
|
||||
if not isinstance(widget, gtk.SeparatorMenuItem):
|
||||
if not isinstance(widget, Gtk.SeparatorMenuItem):
|
||||
def activate_item(widget, target):
|
||||
target.emit('activate')
|
||||
label = widget.get_label()
|
||||
item = gtk.MenuItem(label)
|
||||
item = Gtk.MenuItem(label)
|
||||
item.show()
|
||||
item.connect('activate', activate_item, widget)
|
||||
self.osx_app.insert_app_menu_item(widget, i)
|
||||
i += 1
|
||||
|
||||
def osx_create_dock_menu(self, widgets):
|
||||
menu = gtk.Menu()
|
||||
menu = Gtk.Menu()
|
||||
for widget in widgets:
|
||||
if isinstance(widget, gtk.SeparatorMenuItem):
|
||||
item = gtk.SeparatorMenuItem()
|
||||
if isinstance(widget, Gtk.SeparatorMenuItem):
|
||||
item = Gtk.SeparatorMenuItem()
|
||||
else:
|
||||
def activate_item(widget, target):
|
||||
target.emit('activate')
|
||||
label = widget.get_label()
|
||||
item = gtk.MenuItem(label)
|
||||
item = Gtk.MenuItem(label)
|
||||
item.connect('activate', activate_item, widget)
|
||||
menu.append(item)
|
||||
menu.show_all()
|
||||
@ -721,7 +721,7 @@ class FAHControl(SingleAppServer):
|
||||
return
|
||||
self.quitting = True
|
||||
|
||||
gtk.main_quit()
|
||||
Gtk.main_quit()
|
||||
|
||||
self.viewer_close()
|
||||
|
||||
@ -762,17 +762,17 @@ class FAHControl(SingleAppServer):
|
||||
if theme == name:
|
||||
print(('Loading theme %r' % theme))
|
||||
|
||||
settings = gtk.settings_get_default()
|
||||
settings = Gtk.settings_get_default()
|
||||
|
||||
if rc is None:
|
||||
settings.set_property('gtk-theme-name', self.system_theme)
|
||||
gtk.rc_set_default_files([])
|
||||
Gtk.rc_set_default_files([])
|
||||
else:
|
||||
settings.set_property('gtk-theme-name', theme)
|
||||
gtk.rc_set_default_files([rc])
|
||||
Gtk.rc_set_default_files([rc])
|
||||
|
||||
gtk.rc_reparse_all_for_settings(settings, True)
|
||||
gtk.rc_reset_styles(settings)
|
||||
Gtk.rc_reparse_all_for_settings(settings, True)
|
||||
Gtk.rc_reset_styles(settings)
|
||||
|
||||
break
|
||||
|
||||
@ -1241,7 +1241,7 @@ class FAHControl(SingleAppServer):
|
||||
def get_visible_dialogs(self):
|
||||
dialogs = []
|
||||
for dialog in self.dialogs:
|
||||
if dialog.flags() & gtk.MAPPED:
|
||||
if dialog.flags() & Gtk.MAPPED:
|
||||
dialogs.append(dialog)
|
||||
|
||||
return dialogs
|
||||
@ -1273,7 +1273,7 @@ class FAHControl(SingleAppServer):
|
||||
dialog.destroy()
|
||||
self.error_dialog = None
|
||||
|
||||
def error(self, message, buttons=gtk.BUTTONS_OK, on_response=None,
|
||||
def error(self, message, buttons=Gtk.BUTTONS_OK, on_response=None,
|
||||
on_response_data=None):
|
||||
message = str(message)
|
||||
|
||||
@ -1291,10 +1291,10 @@ class FAHControl(SingleAppServer):
|
||||
|
||||
# create an error message dialog and display modally to the user
|
||||
dialog = \
|
||||
gtk.MessageDialog(None,
|
||||
gtk.DIALOG_MODAL |
|
||||
gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
gtk.MESSAGE_ERROR, buttons, message)
|
||||
Gtk.MessageDialog(None,
|
||||
Gtk.DIALOG_MODAL |
|
||||
Gtk.DIALOG_DESTROY_WITH_PARENT,
|
||||
Gtk.MESSAGE_ERROR, buttons, message)
|
||||
|
||||
dialog.connect('close', self.close_error_dialog)
|
||||
if on_response is not None:
|
||||
@ -1816,7 +1816,7 @@ class FAHControl(SingleAppServer):
|
||||
def on_copy_log_clicked(self, widget, data=None):
|
||||
log = self.log
|
||||
text = log.get_text(log.get_start_iter(), log.get_end_iter())
|
||||
gtk.Clipboard().set_text(text)
|
||||
Gtk.Clipboard().set_text(text)
|
||||
|
||||
def on_clear_log_clicked(self, widget, data=None):
|
||||
if self.active_client:
|
||||
|
@ -26,7 +26,7 @@ viewer_icons = {'tiny': None, 'small': None, 'medium': None, 'large': None}
|
||||
|
||||
|
||||
def load_rgba_pixbuf(data, dim):
|
||||
return gtk.gdk.pixbuf_new_from_data(data, gtk.gdk.COLORSPACE_RGB,
|
||||
return Gtk.gdk.pixbuf_new_from_data(data, Gtk.gdk.COLORSPACE_RGB,
|
||||
True, 8, dim, dim, dim * 4)
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ def get_icon(name):
|
||||
|
||||
|
||||
def get_icon_image(name):
|
||||
image = gtk.Image()
|
||||
image = Gtk.Image()
|
||||
image.set_from_pixbuf(get_icon(name))
|
||||
image.show()
|
||||
|
||||
@ -71,7 +71,7 @@ def get_viewer_icon(name):
|
||||
|
||||
|
||||
def get_viewer_icon_image(name):
|
||||
image = gtk.Image()
|
||||
image = Gtk.Image()
|
||||
image.set_from_pixbuf(get_viewer_icon(name))
|
||||
image.show()
|
||||
|
||||
|
@ -37,7 +37,7 @@ class WidgetMap(dict):
|
||||
def add(self, widget):
|
||||
if widget is None:
|
||||
return
|
||||
name = gtk.Buildable.get_name(widget)
|
||||
name = Gtk.Buildable.get_name(widget)
|
||||
|
||||
if self.suffix is not None:
|
||||
name = name[0:-len(self.suffix)]
|
||||
@ -47,11 +47,11 @@ class WidgetMap(dict):
|
||||
self.list.append(widget)
|
||||
|
||||
def find(self, widget):
|
||||
name = gtk.Buildable.get_name(widget)
|
||||
name = Gtk.Buildable.get_name(widget)
|
||||
|
||||
if (name and (self.suffix is None or name.endswith(self.suffix)) and
|
||||
(self.prefix is None or name.startswith(self.prefix))):
|
||||
self.add(widget)
|
||||
|
||||
if isinstance(widget, gtk.Container):
|
||||
if isinstance(widget, Gtk.Container):
|
||||
widget.foreach(self.find)
|
||||
|
@ -1,23 +1,23 @@
|
||||
################################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
################################################################################
|
||||
###############################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
from UserDict import DictMixin
|
||||
|
||||
@ -115,7 +115,8 @@ class OrderedDict(dict, DictMixin):
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, OrderedDict):
|
||||
return len(self)==len(other) and list(self.items()) == list(other.items())
|
||||
return len(self) == len(other) and \
|
||||
list(self.items()) == list(other.items())
|
||||
return dict.__eq__(self, other)
|
||||
|
||||
def __ne__(self, other):
|
||||
|
@ -1,23 +1,23 @@
|
||||
################################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
################################################################################
|
||||
###############################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import re
|
||||
import json
|
||||
@ -37,180 +37,184 @@ DEFAULT_ENCODING = "utf-8"
|
||||
|
||||
|
||||
def linecol(doc, pos):
|
||||
lineno = doc.count('\n', 0, pos) + 1
|
||||
if lineno == 1:
|
||||
colno = pos + 1
|
||||
else:
|
||||
colno = pos - doc.rindex('\n', 0, pos)
|
||||
return lineno, colno
|
||||
lineno = doc.count('\n', 0, pos) + 1
|
||||
if lineno == 1:
|
||||
colno = pos + 1
|
||||
else:
|
||||
colno = pos - doc.rindex('\n', 0, pos)
|
||||
return lineno, colno
|
||||
|
||||
|
||||
def errmsg(msg, doc, pos, end=None):
|
||||
# Note that this function is called from _json
|
||||
lineno, colno = linecol(doc, pos)
|
||||
if end is None:
|
||||
fmt = '{0}: line {1} column {2} (char {3})'
|
||||
# Note that this function is called from _json
|
||||
lineno, colno = linecol(doc, pos)
|
||||
if end is None:
|
||||
fmt = '{0}: line {1} column {2} (char {3})'
|
||||
return fmt.format(msg, lineno, colno, pos)
|
||||
|
||||
endlineno, endcolno = linecol(doc, end)
|
||||
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
|
||||
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
|
||||
endlineno, endcolno = linecol(doc, end)
|
||||
fmt = '{0}: line {1} column {2} - line {3} column {4} (char {5} - {6})'
|
||||
return fmt.format(msg, lineno, colno, endlineno, endcolno, pos, end)
|
||||
|
||||
|
||||
def _decode_uXXXX(s, pos):
|
||||
esc = s[pos + 1:pos + 5]
|
||||
esc = s[pos + 1:pos + 5]
|
||||
|
||||
if len(esc) == 4 and esc[1] not in 'xX':
|
||||
try:
|
||||
return int(esc, 16)
|
||||
except ValueError: pass
|
||||
if len(esc) == 4 and esc[1] not in 'xX':
|
||||
try:
|
||||
return int(esc, 16)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
msg = "Invalid \\uXXXX escape"
|
||||
raise ValueError(errmsg(msg, s, pos))
|
||||
msg = "Invalid \\uXXXX escape"
|
||||
raise ValueError(errmsg(msg, s, pos))
|
||||
|
||||
|
||||
def pyon_scanstring(s, end, encoding = None, strict = True,
|
||||
_b = BACKSLASH, _m = STRINGCHUNK.match):
|
||||
"""Scan the string s for a JSON string. End is the index of the
|
||||
character in s after the quote that started the JSON string.
|
||||
Unescapes all valid JSON string escape sequences and raises ValueError
|
||||
on attempt to decode an invalid string. If strict is False then literal
|
||||
control characters are allowed in the string.
|
||||
Returns a tuple of the decoded string and the index of the character in s
|
||||
after the end quote."""
|
||||
if encoding is None: encoding = DEFAULT_ENCODING
|
||||
chunks = []
|
||||
_append = chunks.append
|
||||
begin = end - 1
|
||||
def pyon_scanstring(s, end, encoding=None, strict=True,
|
||||
_b=BACKSLASH, _m=STRINGCHUNK.match):
|
||||
"""Scan the string s for a JSON string. End is the index of the
|
||||
character in s after the quote that started the JSON string.
|
||||
Unescapes all valid JSON string escape sequences and raises ValueError
|
||||
on attempt to decode an invalid string. If strict is False then literal
|
||||
control characters are allowed in the string.
|
||||
Returns a tuple of the decoded string and the index of the character in s
|
||||
after the end quote."""
|
||||
|
||||
while True:
|
||||
chunk = _m(s, end)
|
||||
if chunk is None:
|
||||
raise ValueError(
|
||||
errmsg("Unterminated string starting at", s, begin))
|
||||
if encoding is None:
|
||||
encoding = DEFAULT_ENCODING
|
||||
chunks = []
|
||||
_append = chunks.append
|
||||
begin = end - 1
|
||||
|
||||
end = chunk.end()
|
||||
content, terminator = chunk.groups()
|
||||
while True:
|
||||
chunk = _m(s, end)
|
||||
if chunk is None:
|
||||
raise ValueError(
|
||||
errmsg("Unterminated string starting at", s, begin))
|
||||
|
||||
# Content is contains zero or more unescaped string characters
|
||||
if content:
|
||||
if not isinstance(content, str):
|
||||
content = str(content, encoding)
|
||||
_append(content)
|
||||
end = chunk.end()
|
||||
content, terminator = chunk.groups()
|
||||
|
||||
# Terminator is the end of string, a literal control character,
|
||||
# or a backslash denoting that an escape sequence follows
|
||||
if terminator == '"': break
|
||||
elif terminator != '\\':
|
||||
if strict:
|
||||
msg = "Invalid control character {0!r} at".format(terminator)
|
||||
raise ValueError(errmsg(msg, s, end))
|
||||
else:
|
||||
_append(terminator)
|
||||
continue
|
||||
# Content is contains zero or more unescaped string characters
|
||||
if content:
|
||||
if not isinstance(content, str):
|
||||
content = str(content, encoding)
|
||||
_append(content)
|
||||
|
||||
# Terminator is the end of string, a literal control character,
|
||||
# or a backslash denoting that an escape sequence follows
|
||||
if terminator == '"':
|
||||
break
|
||||
elif terminator != '\\':
|
||||
if strict:
|
||||
msg = "Invalid control character {0!r} at".format(terminator)
|
||||
raise ValueError(errmsg(msg, s, end))
|
||||
else:
|
||||
_append(terminator)
|
||||
continue
|
||||
|
||||
try:
|
||||
esc = s[end]
|
||||
esc = s[end]
|
||||
except IndexError:
|
||||
raise ValueError(errmsg("Unterminated string starting at", s, begin))
|
||||
raise ValueError(errmsg("Unterminated string starting at", s, begin))
|
||||
|
||||
# If not a unicode escape sequence, must be in the lookup table
|
||||
if esc != 'u' and esc != 'x':
|
||||
try:
|
||||
char = _b[esc]
|
||||
except KeyError:
|
||||
msg = "Invalid \\escape: " + repr(esc)
|
||||
raise ValueError(errmsg(msg, s, end))
|
||||
end += 1
|
||||
try:
|
||||
char = _b[esc]
|
||||
except KeyError:
|
||||
msg = "Invalid \\escape: " + repr(esc)
|
||||
raise ValueError(errmsg(msg, s, end))
|
||||
end += 1
|
||||
|
||||
elif esc == 'x':
|
||||
# Hex escape sequence
|
||||
code = s[end + 1: end + 3]
|
||||
try:
|
||||
# Hex escape sequence
|
||||
code = s[end + 1: end + 3]
|
||||
try:
|
||||
char = chr(int(code, 16))
|
||||
except:
|
||||
except:
|
||||
raise ValueError(errmsg('Invalid \\escape: ' + repr(code), s, end))
|
||||
|
||||
end += 3
|
||||
end += 3
|
||||
|
||||
else:
|
||||
# Unicode escape sequence
|
||||
uni = _decode_uXXXX(s, end)
|
||||
end += 5
|
||||
# Check for surrogate pair on UCS-4 systems
|
||||
if sys.maxunicode > 65535 and \
|
||||
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':
|
||||
uni2 = _decode_uXXXX(s, end + 1)
|
||||
# Unicode escape sequence
|
||||
uni = _decode_uXXXX(s, end)
|
||||
end += 5
|
||||
# Check for surrogate pair on UCS-4 systems
|
||||
if sys.maxunicode > 65535 and \
|
||||
0xd800 <= uni <= 0xdbff and s[end:end + 2] == '\\u':
|
||||
uni2 = _decode_uXXXX(s, end + 1)
|
||||
if 0xdc00 <= uni2 <= 0xdfff:
|
||||
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
|
||||
end += 6
|
||||
char = chr(uni)
|
||||
uni = 0x10000 + (((uni - 0xd800) << 10) | (uni2 - 0xdc00))
|
||||
end += 6
|
||||
char = chr(uni)
|
||||
|
||||
# Append the unescaped character
|
||||
_append(char)
|
||||
|
||||
return ''.join(chunks), end
|
||||
|
||||
return ''.join(chunks), end
|
||||
|
||||
|
||||
def make_pyon_scanner(context):
|
||||
parse_object = context.parse_object
|
||||
parse_array = context.parse_array
|
||||
parse_string = context.parse_string
|
||||
match_number = NUMBER_RE.match
|
||||
strict = context.strict
|
||||
parse_float = context.parse_float
|
||||
parse_int = context.parse_int
|
||||
parse_constant = context.parse_constant
|
||||
object_hook = context.object_hook
|
||||
object_pairs_hook = context.object_pairs_hook
|
||||
parse_object = context.parse_object
|
||||
parse_array = context.parse_array
|
||||
parse_string = context.parse_string
|
||||
match_number = NUMBER_RE.match
|
||||
strict = context.strict
|
||||
parse_float = context.parse_float
|
||||
parse_int = context.parse_int
|
||||
parse_constant = context.parse_constant
|
||||
object_hook = context.object_hook
|
||||
object_pairs_hook = context.object_pairs_hook
|
||||
|
||||
def scan_once(string, idx):
|
||||
try:
|
||||
nextchar = string[idx]
|
||||
except IndexError:
|
||||
raise StopIteration(idx)
|
||||
|
||||
def scan_once(string, idx):
|
||||
try:
|
||||
nextchar = string[idx]
|
||||
except IndexError:
|
||||
raise StopIteration(idx)
|
||||
|
||||
if nextchar == '"': return parse_string(string, idx + 1, 'utf-8', strict)
|
||||
if nextchar == '"':
|
||||
return parse_string(string, idx + 1, 'utf-8', strict)
|
||||
elif nextchar == '{':
|
||||
return parse_object((string, idx + 1), 'utf-8', strict, scan_once,
|
||||
object_hook, object_pairs_hook)
|
||||
return parse_object((string, idx + 1), 'utf-8', strict, scan_once,
|
||||
object_hook, object_pairs_hook)
|
||||
elif nextchar == '[':
|
||||
return parse_array((string, idx + 1), scan_once)
|
||||
return parse_array((string, idx + 1), scan_once)
|
||||
elif nextchar == 'N' and string[idx:idx + 4] == 'None':
|
||||
return None, idx + 4
|
||||
return None, idx + 4
|
||||
elif nextchar == 'T' and string[idx:idx + 4] == 'True':
|
||||
return True, idx + 4
|
||||
return True, idx + 4
|
||||
elif nextchar == 'F' and string[idx:idx + 5] == 'False':
|
||||
return False, idx + 5
|
||||
return False, idx + 5
|
||||
|
||||
m = match_number(string, idx)
|
||||
if m is not None:
|
||||
integer, frac, exp = m.groups()
|
||||
if frac or exp:
|
||||
res = parse_float(integer + (frac or '') + (exp or ''))
|
||||
else: res = parse_int(integer)
|
||||
integer, frac, exp = m.groups()
|
||||
if frac or exp:
|
||||
res = parse_float(integer + (frac or '') + (exp or ''))
|
||||
else:
|
||||
res = parse_int(integer)
|
||||
|
||||
return res, m.end()
|
||||
return res, m.end()
|
||||
|
||||
elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
|
||||
return parse_constant('NaN'), idx + 3
|
||||
return parse_constant('NaN'), idx + 3
|
||||
|
||||
elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
|
||||
return parse_constant('Infinity'), idx + 8
|
||||
return parse_constant('Infinity'), idx + 8
|
||||
|
||||
elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
|
||||
return parse_constant('-Infinity'), idx + 9
|
||||
return parse_constant('-Infinity'), idx + 9
|
||||
|
||||
else: raise StopIteration(idx)
|
||||
else:
|
||||
raise StopIteration(idx)
|
||||
|
||||
|
||||
return scan_once
|
||||
return scan_once
|
||||
|
||||
|
||||
class PYONDecoder(json.JSONDecoder):
|
||||
def __init__(self, *args, **kwargs):
|
||||
json.JSONDecoder.__init__(self, *args, **kwargs)
|
||||
self.parse_string = pyon_scanstring
|
||||
self.scan_once = make_pyon_scanner(self)
|
||||
def __init__(self, *args, **kwargs):
|
||||
json.JSONDecoder.__init__(self, *args, **kwargs)
|
||||
self.parse_string = pyon_scanstring
|
||||
self.scan_once = make_pyon_scanner(self)
|
||||
|
@ -1,23 +1,23 @@
|
||||
################################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
################################################################################
|
||||
###############################################################################
|
||||
# #
|
||||
# Folding@Home Client Control (FAHControl) #
|
||||
# Copyright (C) 2016-2020 foldingathome.org #
|
||||
# Copyright (C) 2010-2016 Stanford University #
|
||||
# #
|
||||
# This program is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, #
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
||||
# GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import sys
|
||||
import socket
|
||||
@ -46,7 +46,6 @@ class SingleAppRequestHandler(socketserver.BaseRequestHandler):
|
||||
self.request.send('OK\r\n')
|
||||
|
||||
|
||||
|
||||
class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
@ -60,12 +59,11 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
socketserver.TCPServer.__init__(
|
||||
self, single_app_addr, SingleAppRequestHandler)
|
||||
|
||||
thread = threading.Thread(target = self.serve_forever)
|
||||
thread = threading.Thread(target=self.serve_forever)
|
||||
# Exit the server thread when the main thread terminates
|
||||
thread.setDaemon(True)
|
||||
thread.start()
|
||||
|
||||
|
||||
def check_for_instance(self):
|
||||
sock = None
|
||||
try:
|
||||
@ -73,7 +71,7 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
sock.connect(single_app_addr)
|
||||
sock.send('PING')
|
||||
if sock.recv(1024).strip() == 'OK':
|
||||
print ('Already running')
|
||||
print('Already running')
|
||||
sys.exit(1)
|
||||
|
||||
except socket.error:
|
||||
@ -81,4 +79,5 @@ class SingleAppServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
|
||||
return
|
||||
|
||||
finally:
|
||||
if sock is not None: sock.close()
|
||||
if sock is not None:
|
||||
sock.close()
|
||||
|
@ -83,7 +83,7 @@ def get_span_markup(text, bg=None, fg='black'):
|
||||
def iterate_container(widget):
|
||||
yield widget
|
||||
|
||||
if isinstance(widget, gtk.Container):
|
||||
if isinstance(widget, Gtk.Container):
|
||||
for child in widget.get_children():
|
||||
for x in iterate_container(child):
|
||||
yield x
|
||||
@ -109,7 +109,7 @@ def get_combo_items(widget):
|
||||
|
||||
|
||||
def get_widget_str_value(widget):
|
||||
if isinstance(widget, (gtk.SpinButton, gtk.Range)):
|
||||
if isinstance(widget, (Gtk.SpinButton, Gtk.Range)):
|
||||
# Must come before gtk.Entry for gtk.SpinButton
|
||||
|
||||
# Clean up float formatting
|
||||
@ -120,20 +120,20 @@ def get_widget_str_value(widget):
|
||||
value = value[0:-2]
|
||||
return value
|
||||
|
||||
elif isinstance(widget, gtk.Entry):
|
||||
elif isinstance(widget, Gtk.Entry):
|
||||
return widget.get_text()
|
||||
|
||||
elif isinstance(widget, gtk.RadioButton):
|
||||
elif isinstance(widget, Gtk.RadioButton):
|
||||
# TODO interpret as a number? or name?
|
||||
pass
|
||||
|
||||
elif isinstance(widget, gtk.ToggleButton):
|
||||
elif isinstance(widget, Gtk.ToggleButton):
|
||||
if widget.get_active():
|
||||
return 'true'
|
||||
else:
|
||||
return 'false'
|
||||
|
||||
elif isinstance(widget, gtk.ComboBox):
|
||||
elif isinstance(widget, Gtk.ComboBox):
|
||||
# NOTE This does not always get the displayed text
|
||||
return widget.get_active_text()
|
||||
|
||||
@ -146,7 +146,7 @@ def set_widget_str_value(widget, value):
|
||||
value = ''
|
||||
value = str(value)
|
||||
|
||||
if isinstance(widget, (gtk.SpinButton, gtk.Range)):
|
||||
if isinstance(widget, (Gtk.SpinButton, Gtk.Range)):
|
||||
# Must come before gtk.Entry for gtk.SpinButton
|
||||
if value == '':
|
||||
value = 0
|
||||
@ -157,20 +157,20 @@ def set_widget_str_value(widget, value):
|
||||
value = 0
|
||||
widget.set_value(value)
|
||||
|
||||
elif isinstance(widget, (gtk.Entry, gtk.Label)):
|
||||
elif isinstance(widget, (Gtk.Entry, Gtk.Label)):
|
||||
if widget.get_text() != value:
|
||||
widget.set_text(value)
|
||||
elif isinstance(widget, gtk.RadioButton):
|
||||
elif isinstance(widget, Gtk.RadioButton):
|
||||
pass # Ignore for now
|
||||
elif isinstance(widget, gtk.ToggleButton):
|
||||
elif isinstance(widget, Gtk.ToggleButton):
|
||||
widget.set_active(parse_bool(value))
|
||||
elif isinstance(widget, gtk.Button):
|
||||
elif isinstance(widget, Gtk.Button):
|
||||
# NOTE: For some reason setting Button labels causes tooltips to hide.
|
||||
# Only set when it has actually changed.
|
||||
if widget.get_label() != value:
|
||||
widget.set_label(value)
|
||||
|
||||
elif isinstance(widget, gtk.ComboBox):
|
||||
elif isinstance(widget, Gtk.ComboBox):
|
||||
items = get_combo_items(widget)
|
||||
length = len(items)
|
||||
for i in range(length):
|
||||
@ -180,7 +180,7 @@ def set_widget_str_value(widget, value):
|
||||
|
||||
print(('ERROR: Invalid value "%s"' % value))
|
||||
|
||||
elif isinstance(widget, gtk.ProgressBar):
|
||||
elif isinstance(widget, Gtk.ProgressBar):
|
||||
widget.set_text(value)
|
||||
|
||||
if value == '':
|
||||
@ -198,16 +198,16 @@ def set_widget_str_value(widget, value):
|
||||
|
||||
|
||||
def set_widget_change_action(widget, action):
|
||||
if isinstance(widget, (gtk.Editable, gtk.ComboBox)):
|
||||
if isinstance(widget, (Gtk.Editable, Gtk.ComboBox)):
|
||||
widget.connect('changed', action)
|
||||
|
||||
elif isinstance(widget, gtk.Range):
|
||||
elif isinstance(widget, Gtk.Range):
|
||||
widget.connect('value_changed', action)
|
||||
|
||||
elif isinstance(widget, gtk.ToggleButton):
|
||||
elif isinstance(widget, Gtk.ToggleButton):
|
||||
widget.connect('toggled', action)
|
||||
|
||||
elif isinstance(widget, gtk.TreeModel):
|
||||
elif isinstance(widget, Gtk.TreeModel):
|
||||
widget.connect('row_changed', action)
|
||||
widget.connect('row_inserted', action)
|
||||
widget.connect('row_deleted', action)
|
||||
@ -240,5 +240,5 @@ def get_theme_dirs():
|
||||
resources = quartz_application_get_resource_path()
|
||||
path = os.path.join(resources, 'themes')
|
||||
return [get_home_dir() + '/themes', path]
|
||||
return [get_home_dir() + '/themes', gtk.rc_get_theme_dir(),
|
||||
return [get_home_dir() + '/themes', Gtk.rc_get_theme_dir(),
|
||||
'/usr/share/themes']
|
||||
|
@ -24,11 +24,11 @@ import gobject
|
||||
import pango
|
||||
|
||||
|
||||
class WrapLabel(gtk.Label):
|
||||
class WrapLabel(Gtk.Label):
|
||||
__gtype_name__ = 'WrapLabel'
|
||||
|
||||
def __init__(self, str=None):
|
||||
gtk.Label.__init__(self)
|
||||
Gtk.Label.__init__(self)
|
||||
|
||||
self.__wrap_width = 0
|
||||
self.layout = self.get_layout()
|
||||
@ -46,15 +46,15 @@ class WrapLabel(gtk.Label):
|
||||
requisition.height = height
|
||||
|
||||
def do_size_allocate(self, allocation):
|
||||
gtk.Label.do_size_allocate(self, allocation)
|
||||
Gtk.Label.do_size_allocate(self, allocation)
|
||||
self.__set_wrap_width(allocation.width)
|
||||
|
||||
def set_text(self, str):
|
||||
gtk.Label.set_text(self, str)
|
||||
Gtk.Label.set_text(self, str)
|
||||
self.__set_wrap_width(self.__wrap_width)
|
||||
|
||||
def set_markup(self, str):
|
||||
gtk.Label.set_markup(self, str)
|
||||
Gtk.Label.set_markup(self, str)
|
||||
self.__set_wrap_width(self.__wrap_width)
|
||||
|
||||
def __set_wrap_width(self, width):
|
||||
|
Loading…
x
Reference in New Issue
Block a user