gooey.py 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. """DataLad GUI"""
  2. __docformat__ = 'restructuredtext'
  3. from datalad.interface.base import Interface
  4. from datalad.interface.base import build_doc
  5. from datalad.support.param import Parameter
  6. from datalad.distribution.dataset import datasetmethod
  7. from datalad.interface.utils import eval_results
  8. from datalad.interface.results import get_status_dict
  9. import logging
  10. lgr = logging.getLogger('datalad.ext.gooey.gooey')
  11. import sys
  12. # decoration auto-generates standard help
  13. @build_doc
  14. # all commands must be derived from Interface
  15. class Gooey(Interface):
  16. # first docstring line is used a short description in the cmdline help
  17. # the rest is put in the verbose help and manpage
  18. """DataLad GUI
  19. Long description of arbitrary volume.
  20. """
  21. # usage examples
  22. _examples_ = [
  23. dict(
  24. text=(
  25. "Launch the DataLad Graphical User Interface (GUI, a.k.a Gooey) "
  26. "at the specified location."
  27. ),
  28. code_py="gooey(path='path/to/root/explorer/directory')",
  29. code_cmd="datalad gooey --path 'path/to/root/explorer/directory'",
  30. ),
  31. ]
  32. # parameters of the command, must be exhaustive
  33. _params_ = dict(
  34. # name of the parameter, must match argument name
  35. path=Parameter(
  36. # cmdline argument definitions, incl aliases
  37. args=("-p", "--path"),
  38. # documentation
  39. doc="""The root location from which the Gooey file explorer will be
  40. launched (default is current working directory)""",
  41. )
  42. )
  43. @staticmethod
  44. # decorator binds the command to the Dataset class as a method
  45. @datasetmethod(name='gooey')
  46. # generic handling of command results (logging, rendering, filtering, ...)
  47. @eval_results
  48. # signature must match parameter list above
  49. # additional generic arguments are added by decorators
  50. def __call__(path: str = None):
  51. # local import to keep entrypoint import independent of PySide
  52. # availability
  53. from .app import GooeyApp, QApplication
  54. qtapp = QApplication(sys.argv)
  55. if path is None:
  56. from PySide6.QtWidgets import QFileDialog
  57. path = QFileDialog.getExistingDirectory(
  58. caption="Choose directory or dataset",
  59. options=QFileDialog.ShowDirsOnly,
  60. )
  61. gooey = GooeyApp(path)
  62. gooey.main_window.show()
  63. # capture Qt's own exit code for error reporting
  64. qt_exitcode = qtapp.exec()
  65. # tell the app to undo its modifications (UI redirection etc.)
  66. gooey.deinit()
  67. yield get_status_dict(
  68. action='gooey',
  69. path=str(gooey.rootpath),
  70. status='ok' if not qt_exitcode else 'error',
  71. # no message when everything was OK
  72. message='Qt UI errored ' if qt_exitcode else None)