dcscope 2.22.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.
Files changed (267) hide show
  1. dcscope/__init__.py +17 -0
  2. dcscope/__main__.py +44 -0
  3. dcscope/_version.py +21 -0
  4. dcscope/extensions.py +250 -0
  5. dcscope/gui/__init__.py +2 -0
  6. dcscope/gui/analysis/__init__.py +10 -0
  7. dcscope/gui/analysis/ana_basins.py +110 -0
  8. dcscope/gui/analysis/ana_basins.ui +143 -0
  9. dcscope/gui/analysis/ana_filter.py +341 -0
  10. dcscope/gui/analysis/ana_filter.ui +364 -0
  11. dcscope/gui/analysis/ana_log.py +122 -0
  12. dcscope/gui/analysis/ana_log.ui +100 -0
  13. dcscope/gui/analysis/ana_meta.py +207 -0
  14. dcscope/gui/analysis/ana_meta.ui +141 -0
  15. dcscope/gui/analysis/ana_plot.py +638 -0
  16. dcscope/gui/analysis/ana_plot.ui +1060 -0
  17. dcscope/gui/analysis/ana_slot.py +504 -0
  18. dcscope/gui/analysis/ana_slot.ui +684 -0
  19. dcscope/gui/analysis/ana_tables.py +227 -0
  20. dcscope/gui/analysis/ana_tables.ui +195 -0
  21. dcscope/gui/analysis/ana_view.py +69 -0
  22. dcscope/gui/analysis/ana_view.ui +269 -0
  23. dcscope/gui/analysis/dlg_slot_reorder.py +55 -0
  24. dcscope/gui/analysis/dlg_slot_reorder.ui +138 -0
  25. dcscope/gui/bulk/__init__.py +2 -0
  26. dcscope/gui/bulk/bulk_emodulus.py +200 -0
  27. dcscope/gui/bulk/bulk_emodulus.ui +245 -0
  28. dcscope/gui/compute/__init__.py +3 -0
  29. dcscope/gui/compute/comp_lme4.py +115 -0
  30. dcscope/gui/compute/comp_lme4.ui +194 -0
  31. dcscope/gui/compute/comp_lme4_dataset.py +51 -0
  32. dcscope/gui/compute/comp_lme4_dataset.ui +92 -0
  33. dcscope/gui/compute/comp_lme4_results.py +120 -0
  34. dcscope/gui/compute/comp_lme4_results.ui +268 -0
  35. dcscope/gui/compute/comp_stats.py +223 -0
  36. dcscope/gui/compute/comp_stats.ui +187 -0
  37. dcscope/gui/dcor/__init__.py +304 -0
  38. dcscope/gui/dcor/dcor.ui +118 -0
  39. dcscope/gui/export/__init__.py +3 -0
  40. dcscope/gui/export/e2data.py +394 -0
  41. dcscope/gui/export/e2data.ui +367 -0
  42. dcscope/gui/export/e2filter.py +76 -0
  43. dcscope/gui/export/e2filter.ui +111 -0
  44. dcscope/gui/export/e2plot.py +94 -0
  45. dcscope/gui/export/e2plot.ui +175 -0
  46. dcscope/gui/main.py +1089 -0
  47. dcscope/gui/main.ui +579 -0
  48. dcscope/gui/matrix/__init__.py +4 -0
  49. dcscope/gui/matrix/block_matrix.py +141 -0
  50. dcscope/gui/matrix/block_matrix.ui +207 -0
  51. dcscope/gui/matrix/data_matrix.py +574 -0
  52. dcscope/gui/matrix/dm_dataset.py +116 -0
  53. dcscope/gui/matrix/dm_dataset.ui +348 -0
  54. dcscope/gui/matrix/dm_element.py +111 -0
  55. dcscope/gui/matrix/dm_element.ui +169 -0
  56. dcscope/gui/matrix/dm_filter.py +115 -0
  57. dcscope/gui/matrix/dm_filter.ui +287 -0
  58. dcscope/gui/matrix/plot_matrix.py +316 -0
  59. dcscope/gui/matrix/pm_element.py +39 -0
  60. dcscope/gui/matrix/pm_plot.py +86 -0
  61. dcscope/gui/matrix/pm_plot.ui +249 -0
  62. dcscope/gui/pipeline_plot.py +797 -0
  63. dcscope/gui/pipeline_plot.ui +66 -0
  64. dcscope/gui/preferences.py +380 -0
  65. dcscope/gui/preferences.ui +554 -0
  66. dcscope/gui/quick_view/__init__.py +1 -0
  67. dcscope/gui/quick_view/qv_main.py +1072 -0
  68. dcscope/gui/quick_view/qv_main.ui +1297 -0
  69. dcscope/gui/quick_view/qv_scatter.py +284 -0
  70. dcscope/gui/quick_view/qv_style.css +10 -0
  71. dcscope/gui/update.py +90 -0
  72. dcscope/gui/widgets/__init__.py +15 -0
  73. dcscope/gui/widgets/bg_thread.py +29 -0
  74. dcscope/gui/widgets/bulk_list.py +79 -0
  75. dcscope/gui/widgets/bulk_list.ui +95 -0
  76. dcscope/gui/widgets/double_spin_box_nan.py +75 -0
  77. dcscope/gui/widgets/feature_combobox.py +140 -0
  78. dcscope/gui/widgets/get_path.py +42 -0
  79. dcscope/gui/widgets/key_value_table_widget.css +12 -0
  80. dcscope/gui/widgets/key_value_table_widget.py +75 -0
  81. dcscope/gui/widgets/mdi_subwindow_wo_close.py +12 -0
  82. dcscope/gui/widgets/qrangeslider.py +262 -0
  83. dcscope/gui/widgets/rangecontrol.py +308 -0
  84. dcscope/gui/widgets/rangecontrol.ui +136 -0
  85. dcscope/gui/widgets/simple_image_view.py +55 -0
  86. dcscope/gui/widgets/simple_plot_widget.py +113 -0
  87. dcscope/gui/widgets/so_colorbaritem.py +29 -0
  88. dcscope/gui/widgets/wait_cursor.py +33 -0
  89. dcscope/idiom.py +26 -0
  90. dcscope/img/__init__.py +2 -0
  91. dcscope/img/icon-theme/breeze/COPYING-ICONS +209 -0
  92. dcscope/img/icon-theme/breeze/COPYING.LIB +510 -0
  93. dcscope/img/icon-theme/breeze/README +5 -0
  94. dcscope/img/icon-theme/breeze/actions/16/application-exit.svg +17 -0
  95. dcscope/img/icon-theme/breeze/actions/16/code-context.svg +13 -0
  96. dcscope/img/icon-theme/breeze/actions/16/dialog-cancel.svg +13 -0
  97. dcscope/img/icon-theme/breeze/actions/16/dialog-close.svg +17 -0
  98. dcscope/img/icon-theme/breeze/actions/16/dialog-messages.svg +13 -0
  99. dcscope/img/icon-theme/breeze/actions/16/dialog-ok-apply.svg +13 -0
  100. dcscope/img/icon-theme/breeze/actions/16/dialog-ok.svg +13 -0
  101. dcscope/img/icon-theme/breeze/actions/16/document-open-folder.svg +13 -0
  102. dcscope/img/icon-theme/breeze/actions/16/document-open.svg +13 -0
  103. dcscope/img/icon-theme/breeze/actions/16/document-save.svg +13 -0
  104. dcscope/img/icon-theme/breeze/actions/16/documentinfo.svg +12 -0
  105. dcscope/img/icon-theme/breeze/actions/16/draw-watercolor.svg +13 -0
  106. dcscope/img/icon-theme/breeze/actions/16/edit-clear-all.svg +13 -0
  107. dcscope/img/icon-theme/breeze/actions/16/edit-clear.svg +13 -0
  108. dcscope/img/icon-theme/breeze/actions/16/edit-paste.svg +13 -0
  109. dcscope/img/icon-theme/breeze/actions/16/globe.svg +16 -0
  110. dcscope/img/icon-theme/breeze/actions/16/gtk-preferences.svg +13 -0
  111. dcscope/img/icon-theme/breeze/actions/16/list-add.svg +13 -0
  112. dcscope/img/icon-theme/breeze/actions/16/messagebox_warning.svg +20 -0
  113. dcscope/img/icon-theme/breeze/actions/16/object-columns.svg +13 -0
  114. dcscope/img/icon-theme/breeze/actions/16/object-order-lower.svg +13 -0
  115. dcscope/img/icon-theme/breeze/actions/16/object-rows.svg +13 -0
  116. dcscope/img/icon-theme/breeze/actions/16/office-chart-line-stacked.svg +13 -0
  117. dcscope/img/icon-theme/breeze/actions/16/office-chart-ring.svg +13 -0
  118. dcscope/img/icon-theme/breeze/actions/16/office-chart-scatter.svg +13 -0
  119. dcscope/img/icon-theme/breeze/actions/16/path-mode-polyline.svg +13 -0
  120. dcscope/img/icon-theme/breeze/actions/16/preferences-activities.svg +13 -0
  121. dcscope/img/icon-theme/breeze/actions/16/remove.svg +10 -0
  122. dcscope/img/icon-theme/breeze/actions/16/search.svg +13 -0
  123. dcscope/img/icon-theme/breeze/actions/16/show-grid.svg +13 -0
  124. dcscope/img/icon-theme/breeze/actions/16/special_paste.svg +13 -0
  125. dcscope/img/icon-theme/breeze/actions/16/tools-wizard.svg +13 -0
  126. dcscope/img/icon-theme/breeze/actions/16/view-calendar-list.svg +13 -0
  127. dcscope/img/icon-theme/breeze/actions/16/view-filter.svg +13 -0
  128. dcscope/img/icon-theme/breeze/actions/16/view-list-tree.svg +13 -0
  129. dcscope/img/icon-theme/breeze/actions/16/view-statistics.svg +13 -0
  130. dcscope/img/icon-theme/breeze/actions/16/visibility.svg +21 -0
  131. dcscope/img/icon-theme/breeze/actions/22/application-exit.svg +13 -0
  132. dcscope/img/icon-theme/breeze/actions/22/code-context.svg +14 -0
  133. dcscope/img/icon-theme/breeze/actions/22/dialog-cancel.svg +14 -0
  134. dcscope/img/icon-theme/breeze/actions/22/dialog-close.svg +10 -0
  135. dcscope/img/icon-theme/breeze/actions/22/dialog-messages.svg +14 -0
  136. dcscope/img/icon-theme/breeze/actions/22/dialog-ok-apply.svg +14 -0
  137. dcscope/img/icon-theme/breeze/actions/22/dialog-ok.svg +14 -0
  138. dcscope/img/icon-theme/breeze/actions/22/document-open-folder.svg +14 -0
  139. dcscope/img/icon-theme/breeze/actions/22/document-open.svg +14 -0
  140. dcscope/img/icon-theme/breeze/actions/22/document-save.svg +14 -0
  141. dcscope/img/icon-theme/breeze/actions/22/documentinfo.svg +14 -0
  142. dcscope/img/icon-theme/breeze/actions/22/draw-watercolor.svg +14 -0
  143. dcscope/img/icon-theme/breeze/actions/22/edit-clear-all.svg +14 -0
  144. dcscope/img/icon-theme/breeze/actions/22/edit-clear.svg +14 -0
  145. dcscope/img/icon-theme/breeze/actions/22/edit-paste.svg +14 -0
  146. dcscope/img/icon-theme/breeze/actions/22/globe.svg +12 -0
  147. dcscope/img/icon-theme/breeze/actions/22/gtk-preferences.svg +13 -0
  148. dcscope/img/icon-theme/breeze/actions/22/list-add.svg +14 -0
  149. dcscope/img/icon-theme/breeze/actions/22/messagebox_warning.svg +17 -0
  150. dcscope/img/icon-theme/breeze/actions/22/object-columns.svg +14 -0
  151. dcscope/img/icon-theme/breeze/actions/22/object-order-lower.svg +17 -0
  152. dcscope/img/icon-theme/breeze/actions/22/object-rows.svg +17 -0
  153. dcscope/img/icon-theme/breeze/actions/22/office-chart-line-stacked.svg +17 -0
  154. dcscope/img/icon-theme/breeze/actions/22/office-chart-ring.svg +17 -0
  155. dcscope/img/icon-theme/breeze/actions/22/office-chart-scatter.svg +17 -0
  156. dcscope/img/icon-theme/breeze/actions/22/path-mode-polyline.svg +17 -0
  157. dcscope/img/icon-theme/breeze/actions/22/preferences-activities.svg +14 -0
  158. dcscope/img/icon-theme/breeze/actions/22/remove.svg +10 -0
  159. dcscope/img/icon-theme/breeze/actions/22/special_paste.svg +14 -0
  160. dcscope/img/icon-theme/breeze/actions/22/tools-wizard.svg +14 -0
  161. dcscope/img/icon-theme/breeze/actions/22/view-calendar-list.svg +14 -0
  162. dcscope/img/icon-theme/breeze/actions/22/view-filter.svg +14 -0
  163. dcscope/img/icon-theme/breeze/actions/22/view-list-tree.svg +14 -0
  164. dcscope/img/icon-theme/breeze/actions/22/view-statistics.svg +14 -0
  165. dcscope/img/icon-theme/breeze/actions/22/visibility.svg +14 -0
  166. dcscope/img/icon-theme/breeze/actions/24/application-exit.svg +12 -0
  167. dcscope/img/icon-theme/breeze/actions/24/code-context.svg +12 -0
  168. dcscope/img/icon-theme/breeze/actions/24/dialog-cancel.svg +12 -0
  169. dcscope/img/icon-theme/breeze/actions/24/dialog-close.svg +10 -0
  170. dcscope/img/icon-theme/breeze/actions/24/dialog-messages.svg +12 -0
  171. dcscope/img/icon-theme/breeze/actions/24/dialog-ok-apply.svg +12 -0
  172. dcscope/img/icon-theme/breeze/actions/24/dialog-ok.svg +14 -0
  173. dcscope/img/icon-theme/breeze/actions/24/document-open-folder.svg +12 -0
  174. dcscope/img/icon-theme/breeze/actions/24/document-open.svg +12 -0
  175. dcscope/img/icon-theme/breeze/actions/24/document-save.svg +12 -0
  176. dcscope/img/icon-theme/breeze/actions/24/documentinfo.svg +14 -0
  177. dcscope/img/icon-theme/breeze/actions/24/draw-watercolor.svg +12 -0
  178. dcscope/img/icon-theme/breeze/actions/24/edit-clear-all.svg +14 -0
  179. dcscope/img/icon-theme/breeze/actions/24/edit-clear.svg +12 -0
  180. dcscope/img/icon-theme/breeze/actions/24/edit-paste.svg +12 -0
  181. dcscope/img/icon-theme/breeze/actions/24/globe.svg +14 -0
  182. dcscope/img/icon-theme/breeze/actions/24/gtk-preferences.svg +13 -0
  183. dcscope/img/icon-theme/breeze/actions/24/list-add.svg +12 -0
  184. dcscope/img/icon-theme/breeze/actions/24/messagebox_warning.svg +13 -0
  185. dcscope/img/icon-theme/breeze/actions/24/object-columns.svg +12 -0
  186. dcscope/img/icon-theme/breeze/actions/24/object-order-lower.svg +15 -0
  187. dcscope/img/icon-theme/breeze/actions/24/object-rows.svg +15 -0
  188. dcscope/img/icon-theme/breeze/actions/24/office-chart-line-stacked.svg +15 -0
  189. dcscope/img/icon-theme/breeze/actions/24/office-chart-ring.svg +15 -0
  190. dcscope/img/icon-theme/breeze/actions/24/office-chart-scatter.svg +15 -0
  191. dcscope/img/icon-theme/breeze/actions/24/path-mode-polyline.svg +15 -0
  192. dcscope/img/icon-theme/breeze/actions/24/preferences-activities.svg +13 -0
  193. dcscope/img/icon-theme/breeze/actions/24/remove.svg +10 -0
  194. dcscope/img/icon-theme/breeze/actions/24/special_paste.svg +12 -0
  195. dcscope/img/icon-theme/breeze/actions/24/tools-wizard.svg +12 -0
  196. dcscope/img/icon-theme/breeze/actions/24/view-calendar-list.svg +12 -0
  197. dcscope/img/icon-theme/breeze/actions/24/view-filter.svg +12 -0
  198. dcscope/img/icon-theme/breeze/actions/24/view-list-tree.svg +12 -0
  199. dcscope/img/icon-theme/breeze/actions/24/view-statistics.svg +12 -0
  200. dcscope/img/icon-theme/breeze/actions/24/visibility.svg +14 -0
  201. dcscope/img/icon-theme/breeze/actions/32/application-exit.svg +8 -0
  202. dcscope/img/icon-theme/breeze/actions/32/dialog-cancel.svg +13 -0
  203. dcscope/img/icon-theme/breeze/actions/32/dialog-messages.svg +13 -0
  204. dcscope/img/icon-theme/breeze/actions/32/dialog-ok-apply.svg +1 -0
  205. dcscope/img/icon-theme/breeze/actions/32/dialog-ok.svg +1 -0
  206. dcscope/img/icon-theme/breeze/actions/32/document-open-folder.svg +13 -0
  207. dcscope/img/icon-theme/breeze/actions/32/document-open.svg +13 -0
  208. dcscope/img/icon-theme/breeze/actions/32/document-save.svg +18 -0
  209. dcscope/img/icon-theme/breeze/actions/32/gtk-preferences.svg +17 -0
  210. dcscope/img/icon-theme/breeze/actions/32/object-order-lower.svg +18 -0
  211. dcscope/img/icon-theme/breeze/actions/32/view-filter.svg +18 -0
  212. dcscope/img/icon-theme/breeze/actions/32/view-list-tree.svg +18 -0
  213. dcscope/img/icon-theme/breeze/places/16/folder-cloud.svg +13 -0
  214. dcscope/img/icon-theme/breeze/places/16/folder.svg +13 -0
  215. dcscope/img/icon-theme/breeze/places/22/folder-cloud.svg +13 -0
  216. dcscope/img/icon-theme/breeze/places/22/folder.svg +13 -0
  217. dcscope/img/icon-theme/breeze/places/24/folder-cloud.svg +12 -0
  218. dcscope/img/icon-theme/breeze/places/24/folder.svg +12 -0
  219. dcscope/img/icon-theme/breeze/places/32/folder-cloud.svg +35 -0
  220. dcscope/img/icon-theme/breeze/places/32/folder.svg +30 -0
  221. dcscope/img/icon-theme/breeze/places/64/folder-cloud.svg +35 -0
  222. dcscope/img/icon-theme/breeze/places/64/folder.svg +30 -0
  223. dcscope/img/icon-theme/breeze/status/16/dialog-error.svg +9 -0
  224. dcscope/img/icon-theme/breeze/status/16/dialog-information.svg +9 -0
  225. dcscope/img/icon-theme/breeze/status/16/dialog-question.svg +7 -0
  226. dcscope/img/icon-theme/breeze/status/16/dialog-warning.svg +9 -0
  227. dcscope/img/icon-theme/breeze/status/22/dialog-error.svg +9 -0
  228. dcscope/img/icon-theme/breeze/status/22/dialog-information.svg +9 -0
  229. dcscope/img/icon-theme/breeze/status/22/dialog-question.svg +7 -0
  230. dcscope/img/icon-theme/breeze/status/22/dialog-warning.svg +9 -0
  231. dcscope/img/icon-theme/breeze/status/24/dialog-error.svg +13 -0
  232. dcscope/img/icon-theme/breeze/status/24/dialog-information.svg +13 -0
  233. dcscope/img/icon-theme/breeze/status/24/dialog-question.svg +9 -0
  234. dcscope/img/icon-theme/breeze/status/24/dialog-warning.svg +1 -0
  235. dcscope/img/icon-theme/breeze/status/64/dialog-error.svg +25 -0
  236. dcscope/img/icon-theme/breeze/status/64/dialog-information.svg +25 -0
  237. dcscope/img/icon-theme/breeze/status/64/dialog-question.svg +25 -0
  238. dcscope/img/icon-theme/breeze/status/64/dialog-warning.svg +25 -0
  239. dcscope/img/icon-theme/collect_icons.py +124 -0
  240. dcscope/img/icon-theme/dcscope/dcor.png +0 -0
  241. dcscope/img/icon-theme/dcscope/edit-copy-anew.svg +13 -0
  242. dcscope/img/icon-theme/dcscope/emodulus.svg +69 -0
  243. dcscope/img/icon-theme/dcscope/filter_ray.svg +54 -0
  244. dcscope/img/icon-theme/dcscope/region_channel.svg +86 -0
  245. dcscope/img/icon-theme/dcscope/region_reservoir.svg +89 -0
  246. dcscope/img/icon-theme/dcscope/rlang.svg +108 -0
  247. dcscope/img/icon-theme/dcscope/statistical_significance.svg +106 -0
  248. dcscope/img/icon-theme/index.theme +81 -0
  249. dcscope/img/icon.png +0 -0
  250. dcscope/img/icon.svg +73 -0
  251. dcscope/img/splash.png +0 -0
  252. dcscope/meta_tool.py +143 -0
  253. dcscope/pipeline/__init__.py +5 -0
  254. dcscope/pipeline/core.py +632 -0
  255. dcscope/pipeline/dataslot.py +270 -0
  256. dcscope/pipeline/filter.py +161 -0
  257. dcscope/pipeline/filter_ray.py +170 -0
  258. dcscope/pipeline/plot.py +187 -0
  259. dcscope/plot_cache.py +79 -0
  260. dcscope/session.py +379 -0
  261. dcscope/util.py +34 -0
  262. dcscope-2.22.1.dist-info/METADATA +95 -0
  263. dcscope-2.22.1.dist-info/RECORD +267 -0
  264. dcscope-2.22.1.dist-info/WHEEL +5 -0
  265. dcscope-2.22.1.dist-info/entry_points.txt +2 -0
  266. dcscope-2.22.1.dist-info/licenses/LICENSE +621 -0
  267. dcscope-2.22.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,304 @@
1
+ import importlib.resources
2
+ import traceback as tb
3
+ import urllib.parse
4
+ import webbrowser
5
+
6
+ import dclab
7
+ from PyQt6 import uic, QtCore, QtGui, QtWidgets
8
+ import requests
9
+
10
+ from ..widgets import show_wait_cursor, run_async
11
+
12
+
13
+ class DCORLoader(QtWidgets.QDialog):
14
+ search_finished = QtCore.pyqtSignal(int, list, list, object)
15
+ search_item_retrieved = QtCore.pyqtSignal(int, int, dict, dict, str)
16
+
17
+ def __init__(self, parent, *args, **kwargs):
18
+ """Search and load DCOR data"""
19
+ super(DCORLoader, self).__init__(parent=parent, *args, **kwargs)
20
+ ref = importlib.resources.files("dcscope.gui.dcor") / "dcor.ui"
21
+ with importlib.resources.as_file(ref) as path_ui:
22
+ uic.loadUi(path_ui, self)
23
+
24
+ self.main_ui = parent
25
+ self.search_results = []
26
+ self.num_searches = 0
27
+
28
+ # Update UI
29
+ self.settings = QtCore.QSettings()
30
+
31
+ # tool button
32
+ self.pushButton_search.clicked.connect(self.on_search)
33
+ searchicon = QtGui.QIcon.fromTheme("search")
34
+ self.pushButton_search.setIcon(searchicon)
35
+ self.pushButton_search.setDefault(True)
36
+ self.buttonBox.buttons()[1].setDefault(False)
37
+ self.buttonBox.buttons()[0].setDefault(False)
38
+ self.lineEdit_search.setFocus()
39
+
40
+ # search signals
41
+ self.search_finished.connect(self.on_search_finished)
42
+ self.search_item_retrieved.connect(self.on_search_add_result)
43
+
44
+ # button signals
45
+ btn_close = self.buttonBox.button(
46
+ QtWidgets.QDialogButtonBox.StandardButton.Close)
47
+ btn_close.clicked.connect(self.on_close)
48
+ btn_close.setToolTip("Close this window")
49
+ closeicon = QtGui.QIcon.fromTheme("dialog-close")
50
+ btn_close.setIcon(closeicon)
51
+ btn_open = self.buttonBox.button(
52
+ QtWidgets.QDialogButtonBox.StandardButton.Apply)
53
+ btn_open.clicked.connect(self.on_open)
54
+ btn_open.setToolTip("Add selected resources to current session")
55
+ btn_open.setText("Add to session")
56
+ plusicon = QtGui.QIcon.fromTheme("list-add")
57
+ btn_open.setIcon(plusicon)
58
+ btn_help = self.buttonBox.button(
59
+ QtWidgets.QDialogButtonBox.StandardButton.Help)
60
+ btn_help.clicked.connect(self.on_help)
61
+ btn_help.setToolTip("View DCOR Quick Guide online")
62
+ helpicon = QtGui.QIcon.fromTheme("documentinfo")
63
+ btn_help.setIcon(helpicon)
64
+
65
+ def get_api_base_url(self):
66
+ """Return the API url in the form https://dcor.mpl.mpg.de/api/3"""
67
+ server = self.settings.value("dcor/servers", ["dcor.mpl.mpg.de"])[0]
68
+ server = server.strip("/") # remove leading/trailing slashes
69
+ use_ssl = bool(int(self.settings.value("dcor/use ssl", 1)))
70
+ # ready API
71
+ proto = "https" if use_ssl else "http"
72
+ base = f"{proto}://{server}/api/3"
73
+ return base
74
+
75
+ def get_api_headers(self):
76
+ """Return the API headers (Authorization with API key)"""
77
+ api_key = self.settings.value("dcor/api key", "")
78
+ # Add this API Key to the known API keys (dclab)
79
+ dclab.rtdc_dataset.fmt_dcor.api.APIHandler.add_api_key(api_key)
80
+
81
+ if api_key:
82
+ api_headers = {"Authorization": api_key}
83
+ else:
84
+ api_headers = {}
85
+ return api_headers
86
+
87
+ @QtCore.pyqtSlot()
88
+ def on_close(self):
89
+ """Close window"""
90
+ self.close()
91
+
92
+ @show_wait_cursor
93
+ @QtCore.pyqtSlot()
94
+ def on_open(self):
95
+ """Add selected resources to the current session"""
96
+ for ii in range(self.listWidget.count()):
97
+ item = self.listWidget.item(ii)
98
+ if item.isSelected():
99
+ self.main_ui.add_dataslot(
100
+ paths=[self.search_results[ii]], is_dcor=True)
101
+
102
+ @QtCore.pyqtSlot()
103
+ def on_help(self):
104
+ """Show DCscope docs"""
105
+ webbrowser.open(
106
+ "https://dcscope.readthedocs.io/en/stable/sec_qg_dcor.html")
107
+
108
+ @run_async # comment-out for debugging
109
+ @show_wait_cursor
110
+ @QtCore.pyqtSlot()
111
+ def on_search(self):
112
+ """Trigger a search given the current search settings
113
+
114
+ Notes
115
+ -----
116
+ This function is run in a background thread to not block
117
+ the user interface. While this function is running, the
118
+ user may start a new search. For each search, the counter
119
+ ``self.num_searches`` is incremented. After a search is
120
+ complete, the current search id is checked against
121
+ ``self.num_searches`` and only if they match are the
122
+ results displayed in the UI.
123
+
124
+ See Also
125
+ --------
126
+ on_search_add_result: called for every search result
127
+ on_search_finished: called when search finishes
128
+ """
129
+ self.num_searches += 1
130
+ this_search_id = self.num_searches
131
+
132
+ api_base_url = self.get_api_base_url()
133
+ api_headers = self.get_api_headers()
134
+
135
+ # search string
136
+ if self.comboBox_search.currentIndex() == 1:
137
+ stype = "dataset"
138
+ else:
139
+ stype = "free"
140
+ search_string = urllib.parse.quote(self.lineEdit_search.text())
141
+
142
+ # perform search
143
+ try:
144
+ # Results are handled individually via the `search_item_retrieved`
145
+ # event.
146
+ results, failed = self.perform_search(
147
+ search_string=search_string,
148
+ search_type=stype,
149
+ search_id=this_search_id,
150
+ api_base_url=api_base_url,
151
+ api_headers=api_headers,
152
+ )
153
+ except BaseException:
154
+ results = []
155
+ failed = []
156
+ error = tb.format_exc(limit=2, chain=False)
157
+ else:
158
+ error = False
159
+ self.search_finished.emit(this_search_id, results, failed, error)
160
+
161
+ @QtCore.pyqtSlot(int, int, dict, dict, str)
162
+ def on_search_add_result(self, search_id, result_index, dataset, resource,
163
+ api_base_url):
164
+ """Add new item to ``self.listWidget`` and ``self.search_results``"""
165
+ if search_id == self.num_searches:
166
+ if result_index == 0:
167
+ self.listWidget.clear()
168
+ self.search_results.clear()
169
+ name = "{}: {} <{}@{}>".format(
170
+ dataset["title"],
171
+ resource["name"],
172
+ dataset["name"],
173
+ dataset["organization"]["name"],
174
+ )
175
+ self.listWidget.addItem(name)
176
+ ru = api_base_url + "/action/dcserv?id={}".format(resource["id"])
177
+ self.search_results.append(ru)
178
+
179
+ @QtCore.pyqtSlot(int, list, list, object)
180
+ def on_search_finished(self, search_id, results, failed, error):
181
+ """Finalize search
182
+
183
+ Finalization includes:
184
+
185
+ - clear ``self.listWidget`` if the search had no results
186
+ - display messages about datasets that were not displayed
187
+ - display error messages
188
+ """
189
+ if search_id != self.num_searches:
190
+ # user triggered next search
191
+ return
192
+ elif not results:
193
+ # no results for this search
194
+ self.listWidget.clear()
195
+
196
+ if failed:
197
+ msg = QtWidgets.QMessageBox()
198
+ msg.setIcon(QtWidgets.QMessageBox.Information)
199
+ msg.setText("Search found invalid data: {}".format(failed))
200
+ msg.setWindowTitle("Dataset validation")
201
+ msg.exec()
202
+
203
+ if error:
204
+ msg = QtWidgets.QMessageBox()
205
+ msg.setIcon(QtWidgets.QMessageBox.Icon.Critical)
206
+ msg.setText(error)
207
+ msg.setWindowTitle("DCOR access error!")
208
+ msg.exec()
209
+
210
+ def perform_search(self, search_string, search_type, search_id,
211
+ api_base_url, api_headers):
212
+ """Perform search
213
+
214
+ Parameters
215
+ ----------
216
+ search_string: str
217
+ Search string (already parsed using urllib.parse.quote)
218
+ search_type: str
219
+ "free": free text search
220
+ or "dataset": resource/package name/id
221
+ search_id: int
222
+ Search identifier (must match `self.num_searches` for
223
+ the search to continue)
224
+ api_base_url: str
225
+ Everything up until "https://server.example.org/api/3"
226
+ api_headers: dict
227
+ Headers for the request
228
+ """
229
+ if search_type == "free":
230
+ url = api_base_url + "/action/package_search?q={}".format(
231
+ search_string)
232
+ # limit to 20 rows
233
+ url += "&rows=20"
234
+ # include private data
235
+ url += "&include_private=True"
236
+ urls = [url]
237
+ else:
238
+ urls = [
239
+ api_base_url + "/action/package_show?id={}".format(
240
+ search_string),
241
+ api_base_url + "/action/resource_show?id={}".format(
242
+ search_string),
243
+ ]
244
+
245
+ pkg_res = []
246
+ for url in urls:
247
+ req = requests.get(url,
248
+ headers=api_headers,
249
+ verify=get_server_cert_path())
250
+ if not req.ok:
251
+ continue
252
+ resp = req.json()["result"]
253
+ if "count" in resp and "results" in resp:
254
+ # free search
255
+ for pkg in resp["results"]:
256
+ if "resources" in pkg:
257
+ for res in pkg["resources"]:
258
+ pkg_res.append([pkg, res])
259
+ elif "resources" in resp:
260
+ # package show
261
+ for res in resp["resources"]:
262
+ pkg_res.append([resp, res])
263
+ break # no additional search for resource
264
+ else:
265
+ # resource show
266
+ purl = api_base_url + "/action/package_show?id={}".format(
267
+ resp["package_id"])
268
+ pkg = requests.get(purl,
269
+ headers=api_headers,
270
+ verify=get_server_cert_path(),
271
+ ).json()["result"]
272
+ pkg_res.append([pkg, resp])
273
+ break # no additional search for package
274
+
275
+ results = []
276
+ failed = []
277
+ for ii, (pkg, res) in enumerate(pkg_res):
278
+ if res["mimetype"] not in ["RT-DC"]:
279
+ continue # only use RT-DC data
280
+ if search_id != self.num_searches:
281
+ break # stop doing things in the background
282
+ # check availability of each resource
283
+ c = api_base_url + "/action/dcserv?id={}&query=valid".format(
284
+ res["id"])
285
+ req = requests.get(c,
286
+ headers=api_headers,
287
+ verify=get_server_cert_path())
288
+ if req.ok and req.json()["result"]: # only use valid data
289
+ self.search_item_retrieved.emit(search_id, ii, pkg, res,
290
+ api_base_url)
291
+ results.append(res)
292
+ else:
293
+ failed.append("{}: {}".format(res["id"], req.reason))
294
+ return results, failed
295
+
296
+
297
+ def get_server_cert_path(host=None):
298
+ """Return server certificate for current DCOR server if available"""
299
+ settings = QtCore.QSettings()
300
+ if host is None:
301
+ host = settings.value("dcor/servers", ["dcor.mpl.mpg.de"])[0]
302
+ host = host.strip("/") # remove leading/trailing slashes
303
+
304
+ return dclab.rtdc_dataset.fmt_dcor.get_server_cert_path(host)
@@ -0,0 +1,118 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>Dialog</class>
4
+ <widget class="QDialog" name="Dialog">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>653</width>
10
+ <height>416</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>Load DCOR online data</string>
15
+ </property>
16
+ <layout class="QVBoxLayout" name="verticalLayout">
17
+ <item>
18
+ <layout class="QHBoxLayout" name="horizontalLayout">
19
+ <property name="topMargin">
20
+ <number>0</number>
21
+ </property>
22
+ <item>
23
+ <widget class="QComboBox" name="comboBox_search">
24
+ <item>
25
+ <property name="text">
26
+ <string>Free text</string>
27
+ </property>
28
+ </item>
29
+ <item>
30
+ <property name="text">
31
+ <string>Identifier</string>
32
+ </property>
33
+ </item>
34
+ </widget>
35
+ </item>
36
+ <item>
37
+ <widget class="QLineEdit" name="lineEdit_search">
38
+ <property name="placeholderText">
39
+ <string/>
40
+ </property>
41
+ </widget>
42
+ </item>
43
+ <item>
44
+ <widget class="QPushButton" name="pushButton_search">
45
+ <property name="text">
46
+ <string>Search</string>
47
+ </property>
48
+ </widget>
49
+ </item>
50
+ </layout>
51
+ </item>
52
+ <item>
53
+ <widget class="QListWidget" name="listWidget">
54
+ <property name="sizeAdjustPolicy">
55
+ <enum>QAbstractScrollArea::AdjustToContentsOnFirstShow</enum>
56
+ </property>
57
+ <property name="selectionMode">
58
+ <enum>QAbstractItemView::MultiSelection</enum>
59
+ </property>
60
+ <property name="selectionBehavior">
61
+ <enum>QAbstractItemView::SelectRows</enum>
62
+ </property>
63
+ <property name="verticalScrollMode">
64
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
65
+ </property>
66
+ <property name="horizontalScrollMode">
67
+ <enum>QAbstractItemView::ScrollPerPixel</enum>
68
+ </property>
69
+ </widget>
70
+ </item>
71
+ <item>
72
+ <widget class="QDialogButtonBox" name="buttonBox">
73
+ <property name="orientation">
74
+ <enum>Qt::Horizontal</enum>
75
+ </property>
76
+ <property name="standardButtons">
77
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Close|QDialogButtonBox::Help</set>
78
+ </property>
79
+ </widget>
80
+ </item>
81
+ </layout>
82
+ </widget>
83
+ <resources/>
84
+ <connections>
85
+ <connection>
86
+ <sender>buttonBox</sender>
87
+ <signal>accepted()</signal>
88
+ <receiver>Dialog</receiver>
89
+ <slot>accept()</slot>
90
+ <hints>
91
+ <hint type="sourcelabel">
92
+ <x>257</x>
93
+ <y>406</y>
94
+ </hint>
95
+ <hint type="destinationlabel">
96
+ <x>157</x>
97
+ <y>274</y>
98
+ </hint>
99
+ </hints>
100
+ </connection>
101
+ <connection>
102
+ <sender>buttonBox</sender>
103
+ <signal>rejected()</signal>
104
+ <receiver>Dialog</receiver>
105
+ <slot>reject()</slot>
106
+ <hints>
107
+ <hint type="sourcelabel">
108
+ <x>325</x>
109
+ <y>406</y>
110
+ </hint>
111
+ <hint type="destinationlabel">
112
+ <x>286</x>
113
+ <y>274</y>
114
+ </hint>
115
+ </hints>
116
+ </connection>
117
+ </connections>
118
+ </ui>
@@ -0,0 +1,3 @@
1
+ from .e2data import ExportData # noqa: F401
2
+ from .e2filter import ExportFilter # noqa: F401
3
+ from .e2plot import ExportPlot # noqa: F401