gtk-stream 0.7__py3-none-any.whl → 0.7.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
gtk_stream/application.py CHANGED
@@ -20,8 +20,9 @@ from .common import printEvent
20
20
  from .properties import parse_property, get_prop_type
21
21
 
22
22
  class GtkStreamApp(Gtk.Application):
23
- def __init__(self, name = None, **kwargs):
23
+ def __init__(self, logger, name = None, **kwargs):
24
24
  super().__init__(**kwargs)
25
+ self.logger = logger
25
26
  if name != None:
26
27
  GLib.set_application_name(name)
27
28
  self.namedWidgets = { }
@@ -66,7 +67,7 @@ class GtkStreamApp(Gtk.Application):
66
67
  win.set_default_size(int(width), int(height))
67
68
  self.namedWindows[id] = win
68
69
  win.set_child(document.render())
69
- win.connect('close-request', printEvent('close-request', id))
70
+ win.connect('close-request', printEvent(self.logger, 'close-request', id))
70
71
  win.present()
71
72
  return False
72
73
  self.run_when_idle(cb)
@@ -16,22 +16,25 @@
16
16
 
17
17
  import io
18
18
  import xml.sax as sax
19
- import signal
20
19
  import sys
20
+ import os
21
21
 
22
22
  from .parser import GtkStreamXMLHandler
23
+ from .common import Logger, LogLevel
23
24
  from . import GLib
24
25
 
26
+ logLevel = LogLevel.__dict__.get(os.environ.get('GTK_STREAM_LOGLEVEL', 'WARN'), LogLevel.WARN)
27
+
28
+ logger = Logger(logLevel)
29
+
25
30
  class GtkStreamErrorHandler(sax.handler.ErrorHandler):
26
31
  def error(self, exc):
27
- print("Error", file=sys.stderr)
28
32
  raise exc
29
33
  def fatalError(self, exc):
30
- print("Fatal error", file=sys.stderr)
31
34
  raise exc
32
35
 
33
36
  def main():
34
- handler = GtkStreamXMLHandler()
37
+ handler = GtkStreamXMLHandler(logger)
35
38
  errHandler = GtkStreamErrorHandler()
36
39
  parser = sax.make_parser()
37
40
  parser.setContentHandler(handler)
@@ -39,7 +42,5 @@ def main():
39
42
  try:
40
43
  parser.parse(io.FileIO(0, 'r', closefd=False))
41
44
  except Exception as e:
42
- def quit():
43
- handler.app.quit()
44
- GLib.idle_add(quit)
45
- print(f"Done with exception : {e}\n", file=sys.stderr)
45
+ logger.error("Done with exception : %s", e)
46
+ handler.quit_application()
gtk_stream/common.py CHANGED
@@ -15,6 +15,7 @@
15
15
  # along with this program. If not, see <https://www.gnu.org/licenses/>.
16
16
 
17
17
  import sys
18
+ from enum import Enum
18
19
 
19
20
  def _data_str_default(*args):
20
21
  return ''
@@ -23,13 +24,40 @@ def _data_str_by(get_data):
23
24
  return ":"+get_data(*args)
24
25
  return ret
25
26
 
26
- def printEvent(event, id, retval = None, get_data = None):
27
+ def printEvent(logger, event, id, retval = None, get_data = None):
27
28
  data_str = _data_str_default if get_data == None else _data_str_by(get_data)
28
29
  def ret(*args):
29
30
  try:
30
31
  print("{}:{}{}".format(id,event,data_str(*args)), file=sys.stdout)
31
32
  sys.stdout.flush()
32
33
  except Exception as e:
33
- print("Exception when writing an event: {}".format(e), file=sys.stderr)
34
+ logger.error("Exception when writing an event: %s", e)
34
35
  return retval
35
36
  return ret
37
+
38
+ class LogLevel(Enum):
39
+ DEBUG = 0
40
+ INFO = 1
41
+ WARN = 2
42
+ ERROR = 3
43
+
44
+ class Logger:
45
+ def __init__(self, level = LogLevel.WARN, stderr = sys.stderr):
46
+ self.stderr = stderr
47
+ self.level = level
48
+ self.debug = self._initLogger(LogLevel.DEBUG)
49
+ self.info = self._initLogger(LogLevel.INFO)
50
+ self.warn = self._initLogger(LogLevel.WARN)
51
+ self.error = self._initLogger(LogLevel.ERROR)
52
+ def flush(self):
53
+ self.stderr.flush()
54
+
55
+ def _initLogger(self, level):
56
+ if self.level.value <= level.value:
57
+ def ret(fmt, *args):
58
+ print((f"[{level.name}]: {fmt}") % args, file=self.stderr)
59
+ return ret
60
+ else:
61
+ def ret(*args):
62
+ pass
63
+ return ret
@@ -24,7 +24,7 @@ class Button(Document):
24
24
  super().__init__(app, id = id, **kwargs)
25
25
  def render_raw(self):
26
26
  button = Gtk.Button()
27
- button.connect('clicked', printEvent('clicked', self.id))
27
+ button.connect('clicked', printEvent(self.app.logger, 'clicked', self.id))
28
28
  return button
29
29
  def insert_child(self, w, d):
30
30
  w.set_child(d.render())
@@ -35,7 +35,7 @@ class LinkButton(Button):
35
35
  super().__init__(app, id=id, **kwargs)
36
36
  def render_raw(self):
37
37
  button = Gtk.LinkButton()
38
- button.connect('activate-link', printEvent('clicked', self.id, True))
38
+ button.connect('activate-link', printEvent(self.app.logger, 'clicked', self.id, True))
39
39
  return button
40
40
  def insert_child(self, w, d):
41
41
  w.set_child(d.render())
@@ -33,8 +33,9 @@ class Document:
33
33
  def set_properties(self, w):
34
34
  self.app.nameWidget(self.id, w)
35
35
  for (p,v) in self.props.items():
36
- # print(f"Setting property '{p}' to '{v}' in widget {self.__class__}", file=sys.stderr)
37
- w.set_property(p, v(self.app))
36
+ val = v(self.app)
37
+ self.app.logger.debug("Setting property '%s' to '%s' in widget %s", p, val, self.__class__)
38
+ w.set_property(p, val)
38
39
  w.insert_child = lambda d: self.insert_child(w, d)
39
40
  def render(self):
40
41
  w = self.render_raw()
@@ -59,7 +59,7 @@ class Dropdown(Document):
59
59
 
60
60
  ret = Gtk.DropDown(model=model, expression=Gtk.PropertyExpression.new(_ItemObject, None, 'item_value'), factory=factory)
61
61
 
62
- ret.connect('notify::selected-item', printEvent('selected', self.id, get_data = lambda w,_: w.get_selected_item().value))
62
+ ret.connect('notify::selected-item', printEvent(self.app.logger, 'selected', self.id, get_data = lambda w,_: w.get_selected_item().value))
63
63
  return ret
64
64
  def insert_child(self, w, d):
65
65
  pass
@@ -26,7 +26,7 @@ class Switch(Document):
26
26
  self.managed = parse_property('gboolean', managed)(app)
27
27
  def render_raw(self):
28
28
  ret = Gtk.Switch()
29
- ret.connect('state-set', printEvent('switch', self.id,
29
+ ret.connect('state-set', printEvent(self.app.logger, 'switch', self.id,
30
30
  retval = self.managed,
31
31
  get_data = lambda _,state: "on" if state else "off"))
32
32
  return ret
gtk_stream/parser.py CHANGED
@@ -51,13 +51,24 @@ WIDGET_DOCUMENTS = {
51
51
  }
52
52
 
53
53
  class GtkStreamXMLHandler(sax.ContentHandler):
54
- def __init__(self):
54
+ def __init__(self, logger):
55
+ self.logger = logger
55
56
  self.transition_enter = self.transE_conn
56
57
  self.transition_leave = self.transL_final
57
58
  self.transition_chars = self.ignore_chars
58
59
  self.namedWidgets = { }
59
60
  self.windows = { }
60
61
 
62
+ def quit_application(self):
63
+ def cb():
64
+ self.logger.info("Quitting app")
65
+ self.app.quit()
66
+ GLib.idle_add(cb)
67
+ self.logger.info("Waiting for app to terminate")
68
+ self.app_thread.join()
69
+ self.logger.info("App terminated")
70
+ sys.exit(0)
71
+
61
72
  def setNamed(self, attrs, ):
62
73
  if 'id' in attrs:
63
74
  self.namedWidgets[attrs['id']] = widget
@@ -82,20 +93,20 @@ class GtkStreamXMLHandler(sax.ContentHandler):
82
93
  def transE_conn(self, name, attrs):
83
94
  match name:
84
95
  case 'application':
85
- self.app = GtkStreamApp(**attrs)
96
+ self.app = GtkStreamApp(self.logger, **attrs)
86
97
  def on_activate(a):
87
98
  a.hold()
88
99
  self.app.connect('activate', on_activate)
89
100
  def appMain():
90
101
  self.app.run([])
91
- threading.Thread(target = appMain).start()
102
+ self.app_thread = threading.Thread(target = appMain)
103
+ self.app_thread.start()
104
+
92
105
  def on_sigint(a,b):
93
- def cb():
94
- print("SIGINT received", file=sys.stderr)
95
- self.app.quit()
96
- sys.exit(0)
97
- GLib.idle_add(cb)
106
+ self.logger.info("SIGINT received")
107
+ self.quit_application()
98
108
  signal.signal(signal.SIGINT, on_sigint)
109
+
99
110
  self.transition_enter = self.transE_message
100
111
  self.transition_leave = self.transL_tag('application', self.transE_final, self.transL_final)
101
112
  case _:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gtk-stream
3
- Version: 0.7
3
+ Version: 0.7.1
4
4
  Summary: A simple stream-oriented GUI protocol
5
5
  Author-email: Marc Coiffier <marc.coiffier@univ-grenoble-alpes.fr>
6
6
  Project-URL: Homepage, https://coiffier.net/projects/gtk-stream/
@@ -1,14 +1,14 @@
1
1
  gtk_stream/__init__.py,sha256=pDhUSN4AYNsP8_tilU1zmDCYdiv7ak4PE1TW0qFrDlg,99
2
- gtk_stream/application.py,sha256=g95IbeV2fjKf55bRqBCl9EpdiA-sR9XHmp6BMGZBAbo,3836
3
- gtk_stream/command_line.py,sha256=6Yj6NV12cqlnSE5ZHTjNqxE6ZtosuWAiJm66awpJ2H8,1503
4
- gtk_stream/common.py,sha256=wjByU_xhzgCKJFSkEr0gNsi2dqv38kA9_2DodRRrBw4,1310
5
- gtk_stream/parser.py,sha256=9AfSOb-T7O98A-XIH16eBBC6eA0jsFmEVi3F19kAiGY,8063
2
+ gtk_stream/application.py,sha256=gOsJv6AUizfQZrwNe9LxVz9dOKScxzw97XO3lRTmxRs,3886
3
+ gtk_stream/command_line.py,sha256=Ej4mmPiuYjr5-1JrvjGK0BDitKUCfVEI9uHp1p_FAr4,1520
4
+ gtk_stream/common.py,sha256=xdscxYgBg_Ux6iyk26gB-AMSgoUIqlZUPgso5YS_gKE,2106
5
+ gtk_stream/parser.py,sha256=hzy-hHsLAHZb7fQk40fRNY8tOC9onBk5jAOhT904D6Y,8356
6
6
  gtk_stream/properties.py,sha256=r_zxYIBe5g8SGueuhtf5CIAWesmm2tXv6llh6657a74,2374
7
7
  gtk_stream/documents/__init__.py,sha256=_y2h6kINZGuYibRgfgVwtmZGmSdIBHZP0TUB182Ado8,741
8
8
  gtk_stream/documents/classes/Box.py,sha256=d01o2-JQ3-k0VjvvY8E7mly-u_f1v1NqYz1IDjHZLUo,1381
9
- gtk_stream/documents/classes/Button.py,sha256=NoDuAwd2XqXY8ZvyOg9xeKIru71JBi4ZFS3Oe6P478Q,1529
10
- gtk_stream/documents/classes/Document.py,sha256=m_N7UCxHmdlQ34OvP91EvUEdl40CzuRngeJRj9w3dPU,2109
11
- gtk_stream/documents/classes/Dropdown.py,sha256=NUUQ24yrJomlwcXWgm73kEsAsy4Eej6udg77HFBgiZs,2426
9
+ gtk_stream/documents/classes/Button.py,sha256=0Cs5DOt-FoDVLWIktJHuH6OasI58TNI0Gs3uIKJDj2o,1563
10
+ gtk_stream/documents/classes/Document.py,sha256=drWy-2HzgmpxSmRR27uIydlTJbaYTiRJPWwpELXrGSk,2135
11
+ gtk_stream/documents/classes/Dropdown.py,sha256=1azU_iHbr_-099wj0_TDfDfZ5xKyh9xLFd5GvbNMw14,2443
12
12
  gtk_stream/documents/classes/FlowBox.py,sha256=UoVYS2j_osOV-IgbVoaqluTBCiaXus5dq2e9qhAu2Xo,1225
13
13
  gtk_stream/documents/classes/Frame.py,sha256=zAZvsT-YTZMijsgk7p0YVf6siAmFoCCSXouZo9XDpsA,1222
14
14
  gtk_stream/documents/classes/Grid.py,sha256=jDJ9U1GJZ45hi1VvPsCwFILN7CwEkgjqYqhTzMdtX9o,1249
@@ -19,10 +19,10 @@ gtk_stream/documents/classes/ProgressBar.py,sha256=NPJtP3qaKiZUEAYEHZk4FEoWSFn2K
19
19
  gtk_stream/documents/classes/ScrolledWindow.py,sha256=WaTPgz6GBC-hjH83SQT2OGUdCapHAgO3xEmSMJZ8q70,1041
20
20
  gtk_stream/documents/classes/Separator.py,sha256=uw_EgAKs_6pNA8nrOLzruIlJfk4uaogB0p_jeoY0PHM,960
21
21
  gtk_stream/documents/classes/Stack.py,sha256=YA6NDzZL2u4Ko8GXtx8Or-jEWGMCEw2cC1HNkAMRw-8,1030
22
- gtk_stream/documents/classes/Switch.py,sha256=bLOkyAy_v2T_Gli9c6TAhnUJcqhbnxbD9oswPdTAsGo,1365
22
+ gtk_stream/documents/classes/Switch.py,sha256=OLCWWNeVyNrk4Tu3JDe64FqsLhedh3dDzKDKne2CyDw,1382
23
23
  gtk_stream/documents/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- gtk_stream-0.7.dist-info/METADATA,sha256=ReGnW0Nugu54Bbmm4GMDzE0vxxoZBk1Mfy8BQQPzv4c,804
25
- gtk_stream-0.7.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
26
- gtk_stream-0.7.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
27
- gtk_stream-0.7.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
28
- gtk_stream-0.7.dist-info/RECORD,,
24
+ gtk_stream-0.7.1.dist-info/METADATA,sha256=SwTjqF9xkKbnfugzNuA9zOd6Fljaq0AsIC_es6YiY34,806
25
+ gtk_stream-0.7.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
26
+ gtk_stream-0.7.1.dist-info/entry_points.txt,sha256=PmhKTb4MMQM6dN2HJcoDSMI8L0lZIFIlFn-BgdfPDpo,60
27
+ gtk_stream-0.7.1.dist-info/top_level.txt,sha256=vE9zfHGe9Ke7FSe0wBK2WYJI-BpcQNu6xDC3Cu5O8rQ,11
28
+ gtk_stream-0.7.1.dist-info/RECORD,,