Source code for fsleyes.actions.browsexnat

#
# browsexnat.py - Action which allows the user to connect to and browse an
# XNAT repository.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module provides the :class:`BrowseXNATAction`, which allows the user
to connect to and browse an XNAT repository. If ``wxnatpy``
(https://github.com/pauldmccarthy/wxnatpy) is not present, the action is
disabled.
"""


import            os
import os.path as op

import wx

import fsl.utils.settings  as fslsettings
import fsleyes.strings     as strings
import fsleyes.autodisplay as autodisplay

from . import base
from . import loadoverlay

# if wxnatpy is not present, the
# action is permanently disabled
try:
    import wxnat
except ImportError:
    wxnat = None


[docs]class BrowseXNATAction(base.Action): """The ``BrowseXNATAction`` allows the user to open files from an XNAT repository. It opens a :class:`XNATBrowser``, and adds the files that the user selected into the :class:`.OverlayList`. """
[docs] def __init__(self, overlayList, displayCtx, frame): """Create a ``BrowseXNATAction``. :arg overlayList: The :class:`.OverlayList`. :arg displayCtx: The :class:`.DisplayContext`. :arg frame: The :class:`.FSLeyesFrame`. """ base.Action.__init__(self, overlayList, displayCtx, self.__openBrowser) self.__frame = frame if wxnat is None: self.enabled = False
def __openBrowser(self): """Opens a :class:`XNATBrowser`, then adds any files that the user selected to the :class:`.OverlayList`. """ hosts = fslsettings.read('fsleyes.xnat.hosts', []) accounts = fslsettings.read('fsleyes.xnat.accounts', {}) dlg = XNATBrowser(self.__frame, hosts, accounts) dlg.Layout() dlg.Fit() dlg.SetSize((-1, 400)) dlg.CentreOnParent() if dlg.ShowModal() != wx.ID_OK: return paths = dlg.GetPaths() hosts = dlg.GetHosts() accounts = dlg.GetAccounts() # No files downloaded if len(paths) == 0: return # Save successful hosts/credentials fslsettings.write('fsleyes.xnat.hosts', hosts) fslsettings.write('fsleyes.xnat.accounts', accounts) def onLoad(paths, overlays): if len(overlays) == 0: return self.overlayList.extend(overlays) self.displayCtx.selectedOverlay = self.displayCtx.overlayOrder[-1] if self.__displayCtx.autoDisplay: for overlay in overlays: autodisplay.autoDisplay(overlay, self.overlayList, self.displayCtx) loadoverlay.loadOverlays(paths, onLoad=onLoad, saveDir=False, inmem=self.displayCtx.loadInMemory)
[docs]class XNATBrowser(wx.Dialog): """The ``XNATBrowser`` contains a ``wxnat.XNATBrowserPanel``, allowing the user to connect to and browse an XNAT repository. It contains a *Download* button which, when clicked, downloads all selected files from the repository into a temporary directory. Once the files have been downloaded, their paths can be retrieved via the :meth:`GetPaths` method. """
[docs] def __init__(self, parent, knownHosts=None, knownAccounts=None): """Create a ``XNATBrowser``. :arg parent: ``wx`` parent object :arg knownHosts: List of hosts to use as auto-complete options :arg knownAccounts: Mapping containing login credentials, in the ``{ host : (username, password) }``. """ wx.Dialog.__init__(self, parent, title=strings.titles[self], style=wx.RESIZE_BORDER) if wxnat is None: raise RuntimeError('wxnatpy is not available!') filters = {'file' : '*.nii|*.nii.gz|*.img|*.img.gz|*.gii|*.vtk'} self.__panel = wxnat.XNATBrowserPanel( self, knownHosts=knownHosts, knownAccounts=knownAccounts, filterType='glob', filters=filters) self.__ok = wx.Button(self, wx.ID_OK) self.__cancel = wx.Button(self, wx.ID_CANCEL) self.__btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.__sizer = wx.BoxSizer(wx.VERTICAL) self.__ok .SetLabel(strings.labels[self, 'ok']) self.__cancel.SetLabel(strings.labels[self, 'cancel']) self.__btnSizer.Add((10, 1), flag=wx.EXPAND, proportion=1) self.__btnSizer.Add(self.__ok, flag=wx.EXPAND) self.__btnSizer.Add((10, 1), flag=wx.EXPAND) self.__btnSizer.Add(self.__cancel, flag=wx.EXPAND) self.__btnSizer.Add((10, 1), flag=wx.EXPAND) self.__sizer.Add((1, 10), flag=wx.EXPAND) self.__sizer.Add(self.__panel, flag=wx.EXPAND, proportion=1) self.__sizer.Add((1, 10), flag=wx.EXPAND) self.__sizer.Add(self.__btnSizer, flag=wx.EXPAND) self.__sizer.Add((1, 10), flag=wx.EXPAND) self.SetSizer(self.__sizer) self.__ok.SetDefault() self.__panel .Bind(wxnat.EVT_XNAT_FILE_SELECT_EVENT, self.__onOk) self.__ok .Bind(wx.EVT_BUTTON, self.__onOk) self.__cancel.Bind(wx.EVT_BUTTON, self.__onCancel) self.__paths = []
[docs] def GetPaths(self): """Returns paths to the files that were downloaded. """ return self.__paths
[docs] def GetHosts(self): """Wraps ``wxnat.XNATBrowserPanel.GetHosts``. """ return self.__panel.GetHosts()
[docs] def GetAccounts(self): """Wraps ``wxnat.XNATBrowserPanel.GetAccounts``. """ return self.__panel.GetAccounts()
def __onOk(self, ev): """Called when the *Ok* button is pushed. Prompts the user to select a directory, and then downloads the files. """ files = self.__panel.GetSelectedFiles() if len(files) == 0: self.EndModal(wx.ID_OK) destdir = fslsettings.read('fsleyes.xnat.downloaddir', os.getcwd()) dlg = wx.DirDialog(self, strings.labels[self, 'choosedir'], defaultPath=destdir) if dlg.ShowModal() != wx.ID_OK: return destdir = dlg.GetPath() for f in files: dest = self.__panel.DownloadFile(f, op.join(destdir, f.id)) if dest is not None: self.__paths.append(dest) fslsettings.write('fsleyes.xnat.downloaddir', destdir) self.__panel.EndSession() self.EndModal(wx.ID_OK) def __onCancel(self, ev): """Called when the *Cancel* button is pushed. Closes the dialog. """ self.EndModal(wx.ID_CANCEL)