Commit 24de58350db20db24f2267d4ac91feaaf9f24341

Authored by okahilak
Committed by GitHub
1 parent 9d79c88d
Exists in master

ADD: Remote control via Socket.IO (#282)

* ADD: Remote control via Socket.IO

- Add a command line option (--remote-host) to connect to
  a remote server via Socket.IO.

- Add a hook to send all internal events to the remote server using
  `from_neuronavigation` event.

- Add a Socket.IO event listener for `to_neuronavigation` events, send
  publish those events internally.

* FIX: WxPython-UI modifying Socket.IO messages not working

* FIX: Allow sending message to neuronavigation with data None

* Review comments: Create RemoteControl class under invesalius/net

* Review comments: Move invesalius_pubsub dir to invesalius/pubsub

* ADD: Python modules needed by Socket.IO to requirements.txt

* MOD: Move python-socketio to optional-requirements.txt

- Also, change the requirement name from python-socketio to
  python-socketio[client], causing all dependencies needed by the Socket.IO
  client (e.g., requests) to be installed

- Due to that, remove explicit 'requests' library from the requirements

Co-authored-by: Olli-Pekka Kahilakoski <olli-pekka.kahilakoski@aalto.fi>
Showing 54 changed files with 234 additions and 52 deletions   Show diff stats
@@ -51,7 +51,7 @@ try: @@ -51,7 +51,7 @@ try:
51 except ImportError: 51 except ImportError:
52 from wx import SplashScreen 52 from wx import SplashScreen
53 53
54 -from pubsub import pub as Publisher 54 +from invesalius.pubsub import pub as Publisher
55 55
56 #import wx.lib.agw.advancedsplash as agw 56 #import wx.lib.agw.advancedsplash as agw
57 #if sys.platform.startswith('linux'): 57 #if sys.platform.startswith('linux'):
@@ -323,6 +323,10 @@ def parse_comand_line(): @@ -323,6 +323,10 @@ def parse_comand_line():
323 323
324 parser.add_option("--import-folder", action="store", dest="import_folder") 324 parser.add_option("--import-folder", action="store", dest="import_folder")
325 325
  326 + parser.add_option("--remote-host",
  327 + action="store",
  328 + dest="remote_host")
  329 +
326 parser.add_option("-s", "--save", 330 parser.add_option("-s", "--save",
327 help="Save the project after an import.") 331 help="Save the project after an import.")
328 332
@@ -503,6 +507,12 @@ def main(): @@ -503,6 +507,12 @@ def main():
503 """ 507 """
504 options, args = parse_comand_line() 508 options, args = parse_comand_line()
505 509
  510 + if options.remote_host is not None:
  511 + from invesalius.net.remote_control import RemoteControl
  512 +
  513 + remote_control = RemoteControl(options.remote_host)
  514 + remote_control.connect()
  515 +
506 if options.no_gui: 516 if options.no_gui:
507 non_gui_startup(options, args) 517 non_gui_startup(options, args)
508 else: 518 else:
docs/devel/example_pubsub.py
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 # More information about this design pattern can be found at: 3 # More information about this design pattern can be found at:
4 # http://wiki.wxpython.org/ModelViewController 4 # http://wiki.wxpython.org/ModelViewController
5 # http://wiki.wxpython.org/PubSub 5 # http://wiki.wxpython.org/PubSub
6 -from pubsub import pub as Publisher 6 +from invesalius.pubsub import pub as Publisher
7 7
8 # The maintainer of Pubsub module is Oliver Schoenborn. 8 # The maintainer of Pubsub module is Oliver Schoenborn.
9 # Since the end of 2006 Pubsub is now maintained separately on SourceForge at: 9 # Since the end of 2006 Pubsub is now maintained separately on SourceForge at:
docs/devel/example_singleton_pubsub.py
1 # Singleton and Publisher-Subscriber design patterns example. 1 # Singleton and Publisher-Subscriber design patterns example.
2 2
3 -from pubsub import pub as Publisher 3 +from invesalius.pubsub import pub as Publisher
4 4
5 class Singleton(type): 5 class Singleton(type):
6 # This is a Gary Robinson implementation: 6 # This is a Gary Robinson implementation:
invesalius/control.py
@@ -24,7 +24,7 @@ import textwrap @@ -24,7 +24,7 @@ import textwrap
24 import wx 24 import wx
25 import numpy as np 25 import numpy as np
26 26
27 -from pubsub import pub as Publisher 27 +from invesalius.pubsub import pub as Publisher
28 28
29 import invesalius.constants as const 29 import invesalius.constants as const
30 import invesalius.data.imagedata_utils as image_utils 30 import invesalius.data.imagedata_utils as image_utils
invesalius/data/coordinates.py
@@ -26,7 +26,7 @@ import invesalius.constants as const @@ -26,7 +26,7 @@ import invesalius.constants as const
26 26
27 from time import sleep 27 from time import sleep
28 from random import uniform 28 from random import uniform
29 -from pubsub import pub as Publisher 29 +from invesalius.pubsub import pub as Publisher
30 30
31 31
32 def GetCoordinates(trck_init, trck_id, ref_mode): 32 def GetCoordinates(trck_init, trck_id, ref_mode):
invesalius/data/editor.py
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 19
20 import math 20 import math
21 -from pubsub import pub as Publisher 21 +from invesalius.pubsub import pub as Publisher
22 import vtk 22 import vtk
23 23
24 AXIAL = 2 24 AXIAL = 2
invesalius/data/geometry.py
@@ -22,7 +22,7 @@ import math @@ -22,7 +22,7 @@ import math
22 22
23 import numpy as np 23 import numpy as np
24 import vtk 24 import vtk
25 -from pubsub import pub as Publisher 25 +from invesalius.pubsub import pub as Publisher
26 26
27 import invesalius.constants as const 27 import invesalius.constants as const
28 import invesalius.utils as utils 28 import invesalius.utils as utils
invesalius/data/imagedata_utils.py
@@ -27,7 +27,8 @@ import imageio @@ -27,7 +27,8 @@ import imageio
27 import numpy 27 import numpy
28 import numpy as np 28 import numpy as np
29 import vtk 29 import vtk
30 -from pubsub import pub as Publisher 30 +from invesalius.pubsub import pub as Publisher
  31 +
31 from scipy.ndimage import shift, zoom 32 from scipy.ndimage import shift, zoom
32 from vtk.util import numpy_support 33 from vtk.util import numpy_support
33 34
invesalius/data/mask.py
@@ -33,7 +33,7 @@ from invesalius.data.volume import VolumeMask @@ -33,7 +33,7 @@ from invesalius.data.volume import VolumeMask
33 import numpy as np 33 import numpy as np
34 import vtk 34 import vtk
35 from invesalius_cy import floodfill 35 from invesalius_cy import floodfill
36 -from pubsub import pub as Publisher 36 +from invesalius.pubsub import pub as Publisher
37 from scipy import ndimage 37 from scipy import ndimage
38 from vtk.util import numpy_support 38 from vtk.util import numpy_support
39 39
invesalius/data/measures.py
@@ -4,7 +4,7 @@ import math @@ -4,7 +4,7 @@ import math
4 import random 4 import random
5 import sys 5 import sys
6 6
7 -from pubsub import pub as Publisher 7 +from invesalius.pubsub import pub as Publisher
8 8
9 import numpy as np 9 import numpy as np
10 import vtk 10 import vtk
invesalius/data/polydata_utils.py
@@ -21,7 +21,7 @@ import sys @@ -21,7 +21,7 @@ import sys
21 21
22 import vtk 22 import vtk
23 import wx 23 import wx
24 -from pubsub import pub as Publisher 24 +from invesalius.pubsub import pub as Publisher
25 25
26 import invesalius.constants as const 26 import invesalius.constants as const
27 import invesalius.data.vtk_utils as vu 27 import invesalius.data.vtk_utils as vu
invesalius/data/record_coords.py
@@ -23,7 +23,7 @@ import time @@ -23,7 +23,7 @@ import time
23 import wx 23 import wx
24 from numpy import array, savetxt, hstack,vstack, asarray 24 from numpy import array, savetxt, hstack,vstack, asarray
25 import invesalius.gui.dialogs as dlg 25 import invesalius.gui.dialogs as dlg
26 -from pubsub import pub as Publisher 26 +from invesalius.pubsub import pub as Publisher
27 27
28 28
29 class Record(threading.Thread): 29 class Record(threading.Thread):
invesalius/data/slice_.py
@@ -22,7 +22,7 @@ import tempfile @@ -22,7 +22,7 @@ import tempfile
22 import numpy as np 22 import numpy as np
23 import vtk 23 import vtk
24 from scipy import ndimage 24 from scipy import ndimage
25 -from pubsub import pub as Publisher 25 +from invesalius.pubsub import pub as Publisher
26 26
27 import invesalius.constants as const 27 import invesalius.constants as const
28 import invesalius.data.converters as converters 28 import invesalius.data.converters as converters
invesalius/data/styles.py
@@ -31,7 +31,7 @@ from scipy import ndimage @@ -31,7 +31,7 @@ from scipy import ndimage
31 from imageio import imsave 31 from imageio import imsave
32 from scipy.ndimage import generate_binary_structure, watershed_ift 32 from scipy.ndimage import generate_binary_structure, watershed_ift
33 from skimage.morphology import watershed 33 from skimage.morphology import watershed
34 -from pubsub import pub as Publisher 34 +from invesalius.pubsub import pub as Publisher
35 35
36 import invesalius.constants as const 36 import invesalius.constants as const
37 import invesalius.data.converters as converters 37 import invesalius.data.converters as converters
invesalius/data/styles_3d.py
@@ -23,7 +23,7 @@ import wx @@ -23,7 +23,7 @@ import wx
23 import invesalius.constants as const 23 import invesalius.constants as const
24 import invesalius.project as prj 24 import invesalius.project as prj
25 25
26 -from pubsub import pub as Publisher 26 +from invesalius.pubsub import pub as Publisher
27 27
28 28
29 PROP_MEASURE = 0.8 29 PROP_MEASURE = 0.8
invesalius/data/surface.py
@@ -38,7 +38,7 @@ import vtk @@ -38,7 +38,7 @@ import vtk
38 import wx 38 import wx
39 import wx.lib.agw.genericmessagedialog as GMD 39 import wx.lib.agw.genericmessagedialog as GMD
40 40
41 -from pubsub import pub as Publisher 41 +from invesalius.pubsub import pub as Publisher
42 42
43 if sys.platform == 'win32': 43 if sys.platform == 'win32':
44 try: 44 try:
invesalius/data/tractography.py
@@ -28,7 +28,7 @@ import time @@ -28,7 +28,7 @@ import time
28 28
29 import numpy as np 29 import numpy as np
30 import queue 30 import queue
31 -from pubsub import pub as Publisher 31 +from invesalius.pubsub import pub as Publisher
32 from scipy.stats import norm 32 from scipy.stats import norm
33 import vtk 33 import vtk
34 34
invesalius/data/trigger.py
@@ -21,7 +21,7 @@ import threading @@ -21,7 +21,7 @@ import threading
21 from time import sleep 21 from time import sleep
22 22
23 import wx 23 import wx
24 -from pubsub import pub as Publisher 24 +from invesalius.pubsub import pub as Publisher
25 25
26 26
27 class Trigger(threading.Thread): 27 class Trigger(threading.Thread):
invesalius/data/viewer_slice.py
@@ -31,7 +31,7 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor @@ -31,7 +31,7 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
31 import invesalius.data.styles as styles 31 import invesalius.data.styles as styles
32 import wx 32 import wx
33 import sys 33 import sys
34 -from pubsub import pub as Publisher 34 +from invesalius.pubsub import pub as Publisher
35 35
36 try: 36 try:
37 from agw import floatspin as FS 37 from agw import floatspin as FS
invesalius/data/viewer_volume.py
@@ -29,7 +29,7 @@ from numpy.core.umath_tests import inner1d @@ -29,7 +29,7 @@ from numpy.core.umath_tests import inner1d
29 import wx 29 import wx
30 import vtk 30 import vtk
31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor 31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
32 -from pubsub import pub as Publisher 32 +from invesalius.pubsub import pub as Publisher
33 import random 33 import random
34 from scipy.spatial import distance 34 from scipy.spatial import distance
35 35
@@ -622,6 +622,7 @@ class Viewer(wx.Panel): @@ -622,6 +622,7 @@ class Viewer(wx.Panel):
622 622
623 self.ren.AddActor(self.staticballs[self.ball_id]) 623 self.ren.AddActor(self.staticballs[self.ball_id])
624 self.ball_id = self.ball_id + 1 624 self.ball_id = self.ball_id + 1
  625 +
625 #self.UpdateRender() 626 #self.UpdateRender()
626 self.Refresh() 627 self.Refresh()
627 628
invesalius/data/volume.py
@@ -24,7 +24,7 @@ from distutils.version import LooseVersion @@ -24,7 +24,7 @@ from distutils.version import LooseVersion
24 import numpy 24 import numpy
25 import vtk 25 import vtk
26 import wx 26 import wx
27 -from pubsub import pub as Publisher 27 +from invesalius.pubsub import pub as Publisher
28 28
29 import invesalius.constants as const 29 import invesalius.constants as const
30 import invesalius.project as prj 30 import invesalius.project as prj
invesalius/data/vtk_utils.py
@@ -20,7 +20,7 @@ import sys @@ -20,7 +20,7 @@ import sys
20 20
21 import vtk 21 import vtk
22 import wx 22 import wx
23 -from pubsub import pub as Publisher 23 +from invesalius.pubsub import pub as Publisher
24 import invesalius.constants as const 24 import invesalius.constants as const
25 from invesalius.gui.dialogs import ProgressDialog 25 from invesalius.gui.dialogs import ProgressDialog
26 26
invesalius/gui/bitmap_preview_panel.py
@@ -5,7 +5,7 @@ import numpy @@ -5,7 +5,7 @@ import numpy
5 5
6 from vtk.util import numpy_support 6 from vtk.util import numpy_support
7 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor 7 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
8 -from pubsub import pub as Publisher 8 +from invesalius.pubsub import pub as Publisher
9 9
10 import invesalius.constants as const 10 import invesalius.constants as const
11 import invesalius.data.vtk_utils as vtku 11 import invesalius.data.vtk_utils as vtku
invesalius/gui/brain_seg_dialog.py
@@ -12,7 +12,7 @@ import time @@ -12,7 +12,7 @@ import time
12 12
13 import numpy as np 13 import numpy as np
14 import wx 14 import wx
15 -from pubsub import pub as Publisher 15 +from invesalius.pubsub import pub as Publisher
16 16
17 import invesalius.data.slice_ as slc 17 import invesalius.data.slice_ as slc
18 from invesalius.segmentation.brain import segment, utils 18 from invesalius.segmentation.brain import segment, utils
invesalius/gui/data_notebook.py
@@ -34,7 +34,7 @@ except ImportError: @@ -34,7 +34,7 @@ except ImportError:
34 import wx.lib.flatnotebook as fnb 34 import wx.lib.flatnotebook as fnb
35 35
36 import wx.lib.platebtn as pbtn 36 import wx.lib.platebtn as pbtn
37 -from pubsub import pub as Publisher 37 +from invesalius.pubsub import pub as Publisher
38 38
39 import invesalius.constants as const 39 import invesalius.constants as const
40 import invesalius.data.slice_ as slice_ 40 import invesalius.data.slice_ as slice_
invesalius/gui/default_tasks.py
@@ -22,7 +22,7 @@ try: @@ -22,7 +22,7 @@ try:
22 import wx.lib.agw.foldpanelbar as fpb 22 import wx.lib.agw.foldpanelbar as fpb
23 except ModuleNotFoundError: 23 except ModuleNotFoundError:
24 import wx.lib.foldpanelbar as fpb 24 import wx.lib.foldpanelbar as fpb
25 -from pubsub import pub as Publisher 25 +from invesalius.pubsub import pub as Publisher
26 26
27 import invesalius.constants as const 27 import invesalius.constants as const
28 import invesalius.gui.data_notebook as nb 28 import invesalius.gui.data_notebook as nb
invesalius/gui/default_viewers.py
@@ -21,7 +21,7 @@ import os @@ -21,7 +21,7 @@ import os
21 21
22 import wx 22 import wx
23 import wx.lib.agw.fourwaysplitter as fws 23 import wx.lib.agw.fourwaysplitter as fws
24 -from pubsub import pub as Publisher 24 +from invesalius.pubsub import pub as Publisher
25 25
26 import invesalius.data.viewer_slice as slice_viewer 26 import invesalius.data.viewer_slice as slice_viewer
27 import invesalius.data.viewer_volume as volume_viewer 27 import invesalius.data.viewer_volume as volume_viewer
@@ -316,7 +316,7 @@ class VolumeInteraction(wx.Panel): @@ -316,7 +316,7 @@ class VolumeInteraction(wx.Panel):
316 316
317 import wx.lib.platebtn as pbtn 317 import wx.lib.platebtn as pbtn
318 import wx.lib.buttons as btn 318 import wx.lib.buttons as btn
319 -from pubsub import pub as Publisher 319 +from invesalius.pubsub import pub as Publisher
320 import wx.lib.colourselect as csel 320 import wx.lib.colourselect as csel
321 321
322 RAYCASTING_TOOLS = wx.NewId() 322 RAYCASTING_TOOLS = wx.NewId()
invesalius/gui/dialogs.py
@@ -47,7 +47,7 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor @@ -47,7 +47,7 @@ from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
47 from wx.lib import masked 47 from wx.lib import masked
48 from wx.lib.agw import floatspin 48 from wx.lib.agw import floatspin
49 from wx.lib.wordwrap import wordwrap 49 from wx.lib.wordwrap import wordwrap
50 -from pubsub import pub as Publisher 50 +from invesalius.pubsub import pub as Publisher
51 51
52 try: 52 try:
53 from wx.adv import AboutDialogInfo, AboutBox 53 from wx.adv import AboutDialogInfo, AboutBox
invesalius/gui/dicom_preview_panel.py
@@ -29,7 +29,7 @@ import vtk @@ -29,7 +29,7 @@ import vtk
29 29
30 from vtk.util import numpy_support 30 from vtk.util import numpy_support
31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor 31 from vtk.wx.wxVTKRenderWindowInteractor import wxVTKRenderWindowInteractor
32 -from pubsub import pub as Publisher 32 +from invesalius.pubsub import pub as Publisher
33 33
34 import invesalius.constants as const 34 import invesalius.constants as const
35 import invesalius.reader.dicom_reader as dicom_reader 35 import invesalius.reader.dicom_reader as dicom_reader
invesalius/gui/frame.py
@@ -43,7 +43,7 @@ import wx.lib.popupctl as pc @@ -43,7 +43,7 @@ import wx.lib.popupctl as pc
43 from invesalius import inv_paths 43 from invesalius import inv_paths
44 from invesalius.gui import project_properties 44 from invesalius.gui import project_properties
45 from wx.lib.agw.aui.auibar import AUI_TB_PLAIN_BACKGROUND, AuiToolBar 45 from wx.lib.agw.aui.auibar import AUI_TB_PLAIN_BACKGROUND, AuiToolBar
46 -from pubsub import pub as Publisher 46 +from invesalius.pubsub import pub as Publisher
47 47
48 try: 48 try:
49 from wx.adv import TaskBarIcon as wx_TaskBarIcon 49 from wx.adv import TaskBarIcon as wx_TaskBarIcon
invesalius/gui/import_bitmap_panel.py
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 import wx 19 import wx
20 import wx.gizmos as gizmos 20 import wx.gizmos as gizmos
21 -from pubsub import pub as Publisher 21 +from invesalius.pubsub import pub as Publisher
22 import wx.lib.splitter as spl 22 import wx.lib.splitter as spl
23 23
24 import invesalius.constants as const 24 import invesalius.constants as const
invesalius/gui/import_network_panel.py
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 import wx 19 import wx
20 import sys 20 import sys
21 import wx.gizmos as gizmos 21 import wx.gizmos as gizmos
22 -from pubsub import pub as Publisher 22 +from invesalius.pubsub import pub as Publisher
23 import wx.lib.splitter as spl 23 import wx.lib.splitter as spl
24 24
25 import invesalius.constants as const 25 import invesalius.constants as const
invesalius/gui/import_panel.py
@@ -18,7 +18,7 @@ @@ -18,7 +18,7 @@
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 import wx 19 import wx
20 import wx.gizmos as gizmos 20 import wx.gizmos as gizmos
21 -from pubsub import pub as Publisher 21 +from invesalius.pubsub import pub as Publisher
22 import wx.lib.splitter as spl 22 import wx.lib.splitter as spl
23 23
24 import invesalius.constants as const 24 import invesalius.constants as const
invesalius/gui/preferences.py
@@ -4,7 +4,7 @@ import invesalius.constants as const @@ -4,7 +4,7 @@ import invesalius.constants as const
4 import invesalius.session as ses 4 import invesalius.session as ses
5 import wx 5 import wx
6 from invesalius.gui.language_dialog import ComboBoxLanguage 6 from invesalius.gui.language_dialog import ComboBoxLanguage
7 -from pubsub import pub as Publisher 7 +from invesalius.pubsub import pub as Publisher
8 8
9 9
10 class Preferences(wx.Dialog): 10 class Preferences(wx.Dialog):
invesalius/gui/project_properties.py
@@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
19 19
20 import wx 20 import wx
21 import invesalius.project as prj 21 import invesalius.project as prj
22 -from pubsub import pub as Publisher 22 +from invesalius.pubsub import pub as Publisher
23 from invesalius.gui import utils 23 from invesalius.gui import utils
24 from invesalius import constants as const 24 from invesalius import constants as const
25 25
invesalius/gui/task_exporter.py
@@ -29,7 +29,7 @@ except ImportError: @@ -29,7 +29,7 @@ except ImportError:
29 import wx.lib.hyperlink as hl 29 import wx.lib.hyperlink as hl
30 30
31 import wx.lib.platebtn as pbtn 31 import wx.lib.platebtn as pbtn
32 -from pubsub import pub as Publisher 32 +from invesalius.pubsub import pub as Publisher
33 33
34 import invesalius.constants as const 34 import invesalius.constants as const
35 import invesalius.gui.dialogs as dlg 35 import invesalius.gui.dialogs as dlg
invesalius/gui/task_importer.py
@@ -26,7 +26,7 @@ except ImportError: @@ -26,7 +26,7 @@ except ImportError:
26 import wx.lib.hyperlink as hl 26 import wx.lib.hyperlink as hl
27 import wx.lib.platebtn as pbtn 27 import wx.lib.platebtn as pbtn
28 28
29 -from pubsub import pub as Publisher 29 +from invesalius.pubsub import pub as Publisher
30 30
31 import invesalius.constants as const 31 import invesalius.constants as const
32 import invesalius.gui.dialogs as dlg 32 import invesalius.gui.dialogs as dlg
invesalius/gui/task_navigator.py
@@ -42,7 +42,7 @@ except ImportError: @@ -42,7 +42,7 @@ except ImportError:
42 42
43 import wx.lib.colourselect as csel 43 import wx.lib.colourselect as csel
44 import wx.lib.masked.numctrl 44 import wx.lib.masked.numctrl
45 -from pubsub import pub as Publisher 45 +from invesalius.pubsub import pub as Publisher
46 from time import sleep 46 from time import sleep
47 47
48 import invesalius.constants as const 48 import invesalius.constants as const
invesalius/gui/task_slice.py
@@ -31,7 +31,7 @@ except ImportError: @@ -31,7 +31,7 @@ except ImportError:
31 31
32 import wx.lib.platebtn as pbtn 32 import wx.lib.platebtn as pbtn
33 import wx.lib.colourselect as csel 33 import wx.lib.colourselect as csel
34 -from pubsub import pub as Publisher 34 +from invesalius.pubsub import pub as Publisher
35 35
36 import invesalius.data.mask as mask 36 import invesalius.data.mask as mask
37 import invesalius.data.slice_ as slice_ 37 import invesalius.data.slice_ as slice_
invesalius/gui/task_surface.py
@@ -28,7 +28,7 @@ except ImportError: @@ -28,7 +28,7 @@ except ImportError:
28 import wx.lib.hyperlink as hl 28 import wx.lib.hyperlink as hl
29 import wx.lib.foldpanelbar as fpb 29 import wx.lib.foldpanelbar as fpb
30 30
31 -from pubsub import pub as Publisher 31 +from invesalius.pubsub import pub as Publisher
32 import wx.lib.colourselect as csel 32 import wx.lib.colourselect as csel
33 import wx.lib.scrolledpanel as scrolled 33 import wx.lib.scrolledpanel as scrolled
34 34
invesalius/gui/task_tools.py
@@ -27,7 +27,7 @@ except ImportError: @@ -27,7 +27,7 @@ except ImportError:
27 import wx.lib.hyperlink as hl 27 import wx.lib.hyperlink as hl
28 28
29 import wx.lib.platebtn as pbtn 29 import wx.lib.platebtn as pbtn
30 -from pubsub import pub as Publisher 30 +from invesalius.pubsub import pub as Publisher
31 31
32 import invesalius.constants as constants 32 import invesalius.constants as constants
33 import invesalius.constants as const 33 import invesalius.constants as const
invesalius/gui/widgets/canvas_renderer.py
@@ -30,7 +30,7 @@ except ImportError: @@ -30,7 +30,7 @@ except ImportError:
30 from weakrefmethod import WeakMethod 30 from weakrefmethod import WeakMethod
31 31
32 from invesalius.data import converters 32 from invesalius.data import converters
33 -from pubsub import pub as Publisher 33 +from invesalius.pubsub import pub as Publisher
34 34
35 35
36 class CanvasEvent: 36 class CanvasEvent:
invesalius/gui/widgets/clut_raycasting.py
@@ -24,7 +24,7 @@ import sys @@ -24,7 +24,7 @@ import sys
24 24
25 import numpy 25 import numpy
26 import wx 26 import wx
27 -from pubsub import pub as Publisher 27 +from invesalius.pubsub import pub as Publisher
28 28
29 import invesalius.gui.dialogs as dialog 29 import invesalius.gui.dialogs as dialog
30 import invesalius.constants as const 30 import invesalius.constants as const
invesalius/gui/widgets/slice_menu.py
@@ -26,7 +26,7 @@ except(ImportError): @@ -26,7 +26,7 @@ except(ImportError):
26 from ordereddict import OrderedDict 26 from ordereddict import OrderedDict
27 27
28 import wx 28 import wx
29 -from pubsub import pub as Publisher 29 +from invesalius.pubsub import pub as Publisher
30 30
31 import invesalius.constants as const 31 import invesalius.constants as const
32 import invesalius.data.slice_ as sl 32 import invesalius.data.slice_ as sl
invesalius/net/remote_control.py 0 → 100644
@@ -0,0 +1,83 @@ @@ -0,0 +1,83 @@
  1 +#!/usr/bin/env python3
  2 +#--------------------------------------------------------------------------
  3 +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas
  4 +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer
  5 +# Homepage: http://www.softwarepublico.gov.br
  6 +# Contact: invesalius@cti.gov.br
  7 +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt)
  8 +#--------------------------------------------------------------------------
  9 +# Este programa e software livre; voce pode redistribui-lo e/ou
  10 +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme
  11 +# publicada pela Free Software Foundation; de acordo com a versao 2
  12 +# da Licenca.
  13 +#
  14 +# Este programa eh distribuido na expectativa de ser util, mas SEM
  15 +# QUALQUER GARANTIA; sem mesmo a garantia implicita de
  16 +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM
  17 +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
  18 +# detalhes.
  19 +#-------------------------------------------------------------------------
  20 +
  21 +import time
  22 +
  23 +import socketio
  24 +import wx
  25 +
  26 +from invesalius.pubsub import pub as Publisher
  27 +
  28 +class RemoteControl:
  29 + def __init__(self, remote_host):
  30 + self._remote_host = remote_host
  31 + self._connected = False
  32 + self._sio = None
  33 +
  34 + def _on_connect(self):
  35 + print("Connected to {}".format(self._remote_host))
  36 + self._connected = True
  37 +
  38 + def _on_disconnect(self):
  39 + print("Disconnected")
  40 + self._connected = False
  41 +
  42 + def _to_neuronavigation(self, msg):
  43 + topic = msg["topic"]
  44 + data = msg["data"]
  45 + if data is None:
  46 + data = {}
  47 +
  48 + print("Received an event into topic '{}' with data {}".format(topic, str(data)))
  49 + Publisher.sendMessage_no_hook(
  50 + topicName=topic,
  51 + **data
  52 + )
  53 +
  54 + def _to_neuronavigation_wrapper(self, msg):
  55 + # wx.CallAfter wrapping is needed to make messages that update WxPython UI work properly, as the
  56 + # Socket.IO listener runs inside a thread. (See WxPython and thread-safety for more information.)
  57 + wx.CallAfter(self._to_neuronavigation, msg)
  58 +
  59 + def connect(self):
  60 + self._sio = socketio.Client()
  61 +
  62 + self._sio.on('connect', self._on_connect)
  63 + self._sio.on('disconnect', self._on_disconnect)
  64 + self._sio.on('to_neuronavigation', self._to_neuronavigation_wrapper)
  65 +
  66 + self._sio.connect(self._remote_host)
  67 +
  68 + while not self._connected:
  69 + print("Connecting...")
  70 + time.sleep(1.0)
  71 +
  72 + def _emit(topic, data):
  73 + print("Emitting data {} to topic {}".format(data, topic))
  74 + try:
  75 + if isinstance(topic, str):
  76 + self._sio.emit("from_neuronavigation", {
  77 + "topic": topic,
  78 + "data": data,
  79 + })
  80 + except TypeError:
  81 + pass
  82 +
  83 + Publisher.add_sendMessage_hook(_emit)
invesalius/plugins.py
@@ -24,7 +24,7 @@ import pathlib @@ -24,7 +24,7 @@ import pathlib
24 import sys 24 import sys
25 from itertools import chain 25 from itertools import chain
26 26
27 -from pubsub import pub as Publisher 27 +from invesalius.pubsub import pub as Publisher
28 28
29 import invesalius.constants as consts 29 import invesalius.constants as consts
30 from invesalius import inv_paths 30 from invesalius import inv_paths
invesalius/presets.py
@@ -22,7 +22,7 @@ import plistlib @@ -22,7 +22,7 @@ import plistlib
22 22
23 import invesalius.constants as const 23 import invesalius.constants as const
24 24
25 -from pubsub import pub as Publisher 25 +from invesalius.pubsub import pub as Publisher
26 26
27 from invesalius import inv_paths 27 from invesalius import inv_paths
28 from invesalius.utils import TwoWaysDictionary 28 from invesalius.utils import TwoWaysDictionary
invesalius/project.py
@@ -30,7 +30,7 @@ import numpy as np @@ -30,7 +30,7 @@ import numpy as np
30 import vtk 30 import vtk
31 import wx 31 import wx
32 32
33 -from pubsub import pub as Publisher 33 +from invesalius.pubsub import pub as Publisher
34 34
35 import invesalius.constants as const 35 import invesalius.constants as const
36 import invesalius.data.polydata_utils as pu 36 import invesalius.data.polydata_utils as pu
invesalius/pubsub/pub.py 0 → 100644
@@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
  1 +#--------------------------------------------------------------------------
  2 +# Software: InVesalius - Software de Reconstrucao 3D de Imagens Medicas
  3 +# Copyright: (C) 2001 Centro de Pesquisas Renato Archer
  4 +# Homepage: http://www.softwarepublico.gov.br
  5 +# Contact: invesalius@cti.gov.br
  6 +# License: GNU - GPL 2 (LICENSE.txt/LICENCA.txt)
  7 +#--------------------------------------------------------------------------
  8 +# Este programa e software livre; voce pode redistribui-lo e/ou
  9 +# modifica-lo sob os termos da Licenca Publica Geral GNU, conforme
  10 +# publicada pela Free Software Foundation; de acordo com a versao 2
  11 +# da Licenca.
  12 +#
  13 +# Este programa eh distribuido na expectativa de ser util, mas SEM
  14 +# QUALQUER GARANTIA; sem mesmo a garantia implicita de
  15 +# COMERCIALIZACAO ou de ADEQUACAO A QUALQUER PROPOSITO EM
  16 +# PARTICULAR. Consulte a Licenca Publica Geral GNU para obter mais
  17 +# detalhes.
  18 +#--------------------------------------------------------------------------
  19 +
  20 +from typing import Callable
  21 +
  22 +from pubsub import pub as Publisher
  23 +from pubsub.core.listener import UserListener
  24 +
  25 +__all__ = [
  26 + # subscribing
  27 + 'subscribe',
  28 + 'unsubscribe',
  29 +
  30 + # publishing
  31 + 'sendMessage',
  32 + 'sendMessage_no_hook',
  33 +
  34 + # adding hooks
  35 + 'add_sendMessage_hook'
  36 +]
  37 +
  38 +Hook = Callable[[str, dict], None]
  39 +
  40 +sendMessage_hook: Hook = None
  41 +
  42 +def add_sendMessage_hook(hook: Hook):
  43 + """Add a hook for sending messages. The hook is a function that takes the topic
  44 + name as the first parameter and the message dict as the second parameter, and
  45 + returns None.
  46 +
  47 + :param hook:
  48 + """
  49 + global sendMessage_hook
  50 + sendMessage_hook = hook
  51 +
  52 +def subscribe(listener: UserListener, topicName: str, **curriedArgs):
  53 + """Subscribe to a topic.
  54 +
  55 + :param listener:
  56 + :param topicName:
  57 + :param curriedArgs:
  58 + """
  59 + subscribedListener, success = Publisher.subscribe(listener, topicName, **curriedArgs)
  60 + return subscribedListener, success
  61 +
  62 +def unsubscribe(*args, **kwargs):
  63 + """Unsubscribe from a topic.
  64 +
  65 + """
  66 + Publisher.unsubscribe(*args, **kwargs)
  67 +
  68 +def sendMessage(topicName: str, **msgdata):
  69 + """Send a message in a given topic.
  70 +
  71 + :param topicName:
  72 + :param msgdata:
  73 + """
  74 + Publisher.sendMessage(topicName, **msgdata)
  75 + if sendMessage_hook is not None:
  76 + sendMessage_hook(topicName, msgdata)
  77 +
  78 +def sendMessage_no_hook(topicName: str, **msgdata):
  79 + """Send a message in a given topic, but do not call the hook.
  80 +
  81 + :param topicName:
  82 + :param msgdata:
  83 + """
  84 + Publisher.sendMessage(topicName, **msgdata)
  85 +
  86 +AUTO_TOPIC = Publisher.AUTO_TOPIC
invesalius/reader/bitmap_reader.py
@@ -28,7 +28,7 @@ import numpy @@ -28,7 +28,7 @@ import numpy
28 import vtk 28 import vtk
29 import wx 29 import wx
30 from imageio import imread 30 from imageio import imread
31 -from pubsub import pub as Publisher 31 +from invesalius.pubsub import pub as Publisher
32 from vtk.util import numpy_support 32 from vtk.util import numpy_support
33 33
34 import invesalius.constants as const 34 import invesalius.constants as const
invesalius/reader/dicom_reader.py
@@ -28,7 +28,7 @@ import gdcm @@ -28,7 +28,7 @@ import gdcm
28 # Not showing GDCM warning and debug messages 28 # Not showing GDCM warning and debug messages
29 gdcm.Trace_DebugOff() 29 gdcm.Trace_DebugOff()
30 gdcm.Trace_WarningOff() 30 gdcm.Trace_WarningOff()
31 -from pubsub import pub as Publisher 31 +from invesalius.pubsub import pub as Publisher
32 32
33 import invesalius.constants as const 33 import invesalius.constants as const
34 import invesalius.reader.dicom as dicom 34 import invesalius.reader.dicom as dicom
invesalius/session.py
@@ -31,7 +31,7 @@ import codecs @@ -31,7 +31,7 @@ import codecs
31 import collections 31 import collections
32 import json 32 import json
33 33
34 -from pubsub import pub as Publisher 34 +from invesalius.pubsub import pub as Publisher
35 import wx 35 import wx
36 36
37 from invesalius.utils import Singleton, debug, decode, deep_merge_dict 37 from invesalius.utils import Singleton, debug, decode, deep_merge_dict
invesalius/style.py
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 # detalhes. 17 # detalhes.
18 #-------------------------------------------------------------------------- 18 #--------------------------------------------------------------------------
19 19
20 -from pubsub import pub as Publisher 20 +from invesalius.pubsub import pub as Publisher
21 21
22 22
23 # mode.py 23 # mode.py
optional-requirements.txt
1 mido==1.2.10 1 mido==1.2.10
2 python-rtmidi==1.4.9 2 python-rtmidi==1.4.9
  3 +python-socketio[client]==5.3.0