itkdb-gtk 0.0.12__py3-none-any.whl → 0.0.16__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.
Potentially problematic release.
This version of itkdb-gtk might be problematic. Click here for more details.
- itkdb_gtk/{getShipments.py → GetShipments.py} +9 -8
- itkdb_gtk/GlueWeight.py +8 -5
- itkdb_gtk/{gndVITests.py → GroundVITests.py} +41 -8
- itkdb_gtk/ITkDBlogin.py +1 -0
- itkdb_gtk/ITkDButils.py +6 -2
- itkdb_gtk/{sendShipments.py → SendShipments.py} +9 -7
- itkdb_gtk/ShowAttachments.py +136 -8
- itkdb_gtk/ShowComments.py +12 -3
- itkdb_gtk/ShowDefects.py +17 -5
- itkdb_gtk/UploadModuleIV.py +857 -0
- itkdb_gtk/{uploadMultipleTests.py → UploadMultipleTests.py} +13 -15
- itkdb_gtk/{uploadPetalInformation.py → UploadPetalInformation.py} +9 -9
- itkdb_gtk/{uploadTest.py → UploadTest.py} +87 -49
- itkdb_gtk/WireBondGui.py +863 -0
- itkdb_gtk/__init__.py +19 -11
- itkdb_gtk/dashBoard.py +68 -21
- itkdb_gtk/dbGtkUtils.py +189 -40
- itkdb_gtk/readAVSdata.py +8 -4
- itkdb_gtk/readGoogleSheet.py +1 -1
- itkdb_gtk/untrash_component.py +35 -0
- {itkdb_gtk-0.0.12.dist-info → itkdb_gtk-0.0.16.dist-info}/METADATA +16 -11
- itkdb_gtk-0.0.16.dist-info/RECORD +27 -0
- {itkdb_gtk-0.0.12.dist-info → itkdb_gtk-0.0.16.dist-info}/WHEEL +1 -1
- {itkdb_gtk-0.0.12.dist-info → itkdb_gtk-0.0.16.dist-info}/entry_points.txt +3 -1
- itkdb_gtk/checkComponent.py +0 -151
- itkdb_gtk/checkJSon.py +0 -56
- itkdb_gtk-0.0.12.dist-info/RECORD +0 -26
- {itkdb_gtk-0.0.12.dist-info → itkdb_gtk-0.0.16.dist-info}/top_level.txt +0 -0
itkdb_gtk/__init__.py
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
__version__ = "0.0.12"
|
|
1
|
+
__version__ = "0.0.16"
|
|
4
2
|
|
|
5
3
|
|
|
6
4
|
def dash_board():
|
|
7
5
|
"""Launches the dash board."""
|
|
6
|
+
from .dashBoard import main
|
|
8
7
|
dashBoard.main()
|
|
9
8
|
|
|
10
9
|
|
|
11
10
|
def getShipments():
|
|
12
11
|
"""getShipments."""
|
|
13
|
-
from .
|
|
12
|
+
from .GetShipments import main
|
|
14
13
|
main()
|
|
15
14
|
|
|
16
15
|
|
|
@@ -20,25 +19,34 @@ def glueWeight():
|
|
|
20
19
|
main()
|
|
21
20
|
|
|
22
21
|
|
|
23
|
-
def
|
|
22
|
+
def groundVITests():
|
|
24
23
|
"""GND/VI tests."""
|
|
25
|
-
from .
|
|
24
|
+
from .GroundVITests import main
|
|
26
25
|
main()
|
|
27
26
|
|
|
28
27
|
|
|
29
28
|
def sendShipments():
|
|
30
29
|
"""Send items."""
|
|
31
|
-
from .
|
|
30
|
+
from .SendShipments import main
|
|
32
31
|
main()
|
|
33
32
|
|
|
34
|
-
|
|
35
33
|
def uploadTest():
|
|
36
|
-
"""Upload tests."""
|
|
37
|
-
from .
|
|
34
|
+
"""Upload a single tests."""
|
|
35
|
+
from .UploadTest import main
|
|
38
36
|
main()
|
|
39
37
|
|
|
40
38
|
|
|
41
39
|
def uploadMultipleTests():
|
|
42
40
|
"""Upload multiple tests."""
|
|
43
|
-
from .
|
|
41
|
+
from .UploadMultipleTests import main
|
|
42
|
+
main()
|
|
43
|
+
|
|
44
|
+
def uploadModuleIV():
|
|
45
|
+
"""Upload IV files of single and double modules"""
|
|
46
|
+
from .UploadModuleIV import main
|
|
47
|
+
main()
|
|
48
|
+
|
|
49
|
+
def wirebondTest():
|
|
50
|
+
"""Inputs data and eventually upload wirebod test."""
|
|
51
|
+
from .WireBondGui import main
|
|
44
52
|
main()
|
itkdb_gtk/dashBoard.py
CHANGED
|
@@ -3,16 +3,23 @@
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
5
|
try:
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
6
|
+
import itkdb_gtk
|
|
7
|
+
|
|
8
|
+
except ImportError:
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
cwd = Path(sys.argv[0]).parent.parent
|
|
11
|
+
sys.path.append(cwd.as_posix())
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
from itkdb_gtk import dbGtkUtils
|
|
15
|
+
from itkdb_gtk import GetShipments
|
|
16
|
+
from itkdb_gtk import GroundVITests
|
|
17
|
+
from itkdb_gtk import ITkDBlogin
|
|
18
|
+
from itkdb_gtk import SendShipments
|
|
19
|
+
from itkdb_gtk import UploadMultipleTests
|
|
20
|
+
from itkdb_gtk import GlueWeight
|
|
21
|
+
from itkdb_gtk import UploadModuleIV
|
|
22
|
+
from itkdb_gtk import WireBondGui
|
|
16
23
|
|
|
17
24
|
import gi
|
|
18
25
|
|
|
@@ -22,7 +29,14 @@ from gi.repository import Gtk
|
|
|
22
29
|
|
|
23
30
|
class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
24
31
|
"""Dashboard class."""
|
|
25
|
-
|
|
32
|
+
UPLOAD_TEST = 1
|
|
33
|
+
CREATE_SHIPMNT = 2
|
|
34
|
+
RECV_SHIPMNT = 3
|
|
35
|
+
PETAL_GND = 4
|
|
36
|
+
GLUE_WEIGHT = 5
|
|
37
|
+
MOD_IV = 6
|
|
38
|
+
WIRE_BOND = 7
|
|
39
|
+
|
|
26
40
|
def __init__(self, session):
|
|
27
41
|
"""Initialization."""
|
|
28
42
|
super().__init__(title="ITkDB Dashboard", session=session)
|
|
@@ -59,6 +73,17 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
59
73
|
btnWeight.connect("clicked", self.glue_weight)
|
|
60
74
|
grid.attach(btnWeight, 0, irow, 1, 1)
|
|
61
75
|
|
|
76
|
+
btnModIV = Gtk.Button(label="Module IV")
|
|
77
|
+
btnModIV.connect("clicked", self.module_IV)
|
|
78
|
+
grid.attach(btnModIV, 1, irow, 1, 1)
|
|
79
|
+
|
|
80
|
+
irow +=1
|
|
81
|
+
btnWireBond = Gtk.Button(label="Wire Bond")
|
|
82
|
+
btnWireBond.connect("clicked", self.wire_bond)
|
|
83
|
+
grid.attach(btnWireBond, 0, irow, 1, 1)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
62
87
|
irow += 1
|
|
63
88
|
grid.attach(Gtk.Label(), 0, irow, 1, 1)
|
|
64
89
|
|
|
@@ -83,51 +108,51 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
83
108
|
|
|
84
109
|
def upload_test(self, *args):
|
|
85
110
|
"""Launch upload test."""
|
|
86
|
-
bitn =
|
|
111
|
+
bitn = DashWindow.UPLOAD_TEST
|
|
87
112
|
bt = 1 << bitn
|
|
88
113
|
if self.mask & bt:
|
|
89
114
|
return
|
|
90
115
|
|
|
91
116
|
self.mask |= bt
|
|
92
|
-
W =
|
|
117
|
+
W = UploadMultipleTests.UploadMultipleTests(self.session)
|
|
93
118
|
W.connect("destroy", self.app_closed, bitn)
|
|
94
119
|
|
|
95
120
|
def create_shipment(self, *args):
|
|
96
121
|
"""Launch sendShipment."""
|
|
97
|
-
bitn =
|
|
122
|
+
bitn = DashWindow.CREATE_SHIPMNT
|
|
98
123
|
bt = 1 << bitn
|
|
99
124
|
if self.mask & bt:
|
|
100
125
|
return
|
|
101
126
|
|
|
102
127
|
self.mask |= bt
|
|
103
|
-
W =
|
|
128
|
+
W = SendShipments.SendShipments(self.session)
|
|
104
129
|
W.connect("destroy", self.app_closed, bitn)
|
|
105
130
|
|
|
106
131
|
def receive_shipment(self, *args):
|
|
107
132
|
"""Launch getShipments."""
|
|
108
|
-
bitn =
|
|
133
|
+
bitn = DashWindow.RECV_SHIPMNT
|
|
109
134
|
bt = 1 << bitn
|
|
110
135
|
if self.mask & bt:
|
|
111
136
|
return
|
|
112
137
|
|
|
113
138
|
self.mask |= bt
|
|
114
|
-
W =
|
|
139
|
+
W = GetShipments.ReceiveShipments(self.session)
|
|
115
140
|
W.connect("destroy", self.app_closed, bitn)
|
|
116
141
|
|
|
117
142
|
def petal_gnd(self, *args):
|
|
118
143
|
"""Petal GND/VI test."""
|
|
119
|
-
bitn =
|
|
144
|
+
bitn = DashWindow.PETAL_GND
|
|
120
145
|
bt = 1 << bitn
|
|
121
146
|
if self.mask & bt:
|
|
122
147
|
return
|
|
123
148
|
|
|
124
149
|
self.mask |= bt
|
|
125
|
-
W =
|
|
150
|
+
W = GroundVITests.GroundingTest(self.session)
|
|
126
151
|
W.connect("destroy", self.app_closed, bitn)
|
|
127
152
|
|
|
128
153
|
def glue_weight(self, *args):
|
|
129
154
|
"""Glue Weight test."""
|
|
130
|
-
bitn =
|
|
155
|
+
bitn = DashWindow.GLUE_WEIGHT
|
|
131
156
|
bt = 1 << bitn
|
|
132
157
|
if self.mask & bt:
|
|
133
158
|
return
|
|
@@ -136,11 +161,33 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
136
161
|
W = GlueWeight.GlueWeight(self.session)
|
|
137
162
|
W.connect("destroy", self.app_closed, bitn)
|
|
138
163
|
|
|
164
|
+
def module_IV(self, *args):
|
|
165
|
+
"""Module IV tests."""
|
|
166
|
+
bitn = DashWindow.MOD_IV
|
|
167
|
+
bt = 1 << bitn
|
|
168
|
+
if self.mask & bt:
|
|
169
|
+
return
|
|
170
|
+
|
|
171
|
+
self.mask |= bt
|
|
172
|
+
W = UploadModuleIV.IVwindow(self.session)
|
|
173
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
174
|
+
|
|
175
|
+
def wire_bond(self, *args):
|
|
176
|
+
"""Module IV tests."""
|
|
177
|
+
bitn = DashWindow.WIRE_BOND
|
|
178
|
+
bt = 1 << bitn
|
|
179
|
+
if self.mask & bt:
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
self.mask |= bt
|
|
183
|
+
W = WireBondGui.WireBond(session=self.session, title="Wirebond")
|
|
184
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
185
|
+
|
|
139
186
|
def app_closed(self, *args):
|
|
140
187
|
"""Application window closed. Clear mask."""
|
|
141
188
|
bt = 1 << args[1]
|
|
142
189
|
self.mask &= ~bt
|
|
143
|
-
print(bt, self.mask)
|
|
190
|
+
# print(bt, self.mask)
|
|
144
191
|
|
|
145
192
|
|
|
146
193
|
def main():
|
itkdb_gtk/dbGtkUtils.py
CHANGED
|
@@ -7,33 +7,72 @@ from datetime import datetime
|
|
|
7
7
|
|
|
8
8
|
import dateutil.parser
|
|
9
9
|
import gi
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
10
12
|
|
|
11
13
|
gi.require_version("Gtk", "3.0")
|
|
12
|
-
from gi.repository import Gtk, Gio, GLib
|
|
14
|
+
from gi.repository import Gtk, GObject, Gio, GLib
|
|
13
15
|
|
|
16
|
+
def parse_date(txt):
|
|
17
|
+
"""Parse a date."""
|
|
18
|
+
try:
|
|
19
|
+
return dateutil.parser.parse(txt, fuzzy=False)
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
combo.set_active_iter(iter)
|
|
23
|
-
break
|
|
21
|
+
except Exception:
|
|
22
|
+
return None
|
|
23
|
+
def parse_date_as_string(txt):
|
|
24
|
+
"""Parse data and return DB compatible string."""
|
|
25
|
+
D = parse_date(txt)
|
|
26
|
+
if D is None:
|
|
27
|
+
return D
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
out = D.isoformat(timespec='milliseconds')
|
|
30
|
+
if out[-1] not in ['zZ']:
|
|
31
|
+
out += 'Z'
|
|
32
|
+
|
|
33
|
+
return out
|
|
34
|
+
|
|
35
|
+
def is_a_date(txt):
|
|
36
|
+
"""check tha the input string is a date."""
|
|
37
|
+
try:
|
|
38
|
+
dateutil.parser.parse(txt, fuzzy=False)
|
|
39
|
+
return True
|
|
26
40
|
|
|
41
|
+
except Exception:
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
def new_small_text_entry():
|
|
45
|
+
"""Returs a new, smaller Gtk.Entry."""
|
|
46
|
+
entry = Gtk.Entry()
|
|
47
|
+
provider = Gtk.CssProvider()
|
|
48
|
+
style_context = entry.get_style_context()
|
|
49
|
+
font_size = 2.25*style_context.get_property("font-size", 0)
|
|
50
|
+
css = "entry {{ min-height: {}px; }}".format(font_size)
|
|
51
|
+
provider.load_from_data(css.encode())
|
|
52
|
+
style_context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_SETTINGS)
|
|
53
|
+
return entry
|
|
27
54
|
|
|
28
55
|
def set_entry_style(container):
|
|
29
56
|
"""Set max entry."""
|
|
30
57
|
provider = Gtk.CssProvider()
|
|
31
|
-
print(container.get_name())
|
|
32
58
|
style_context = container.get_style_context()
|
|
33
59
|
font_size = 2.25*style_context.get_property("font-size", 0)
|
|
34
60
|
css = "{} {{ min-height: {}px; }}".format(container.get_name(), font_size)
|
|
35
61
|
provider.load_from_data(css.encode())
|
|
36
62
|
style_context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_SETTINGS)
|
|
63
|
+
return container
|
|
64
|
+
|
|
65
|
+
def set_combo_iter(combo, txt, col=0):
|
|
66
|
+
"""Set scombo active iter to that containing txt in column col."""
|
|
67
|
+
model = combo.get_model()
|
|
68
|
+
iter = model.get_iter_first()
|
|
69
|
+
while iter:
|
|
70
|
+
val = model.get_value(iter, col)
|
|
71
|
+
if val == txt:
|
|
72
|
+
combo.set_active_iter(iter)
|
|
73
|
+
break
|
|
74
|
+
|
|
75
|
+
iter = model.iter_next(iter)
|
|
37
76
|
|
|
38
77
|
|
|
39
78
|
def is_iterable(obj):
|
|
@@ -55,6 +94,12 @@ class MyEncoder(json.JSONEncoder):
|
|
|
55
94
|
if isinstance(o, datetime):
|
|
56
95
|
text = o.astimezone().isoformat()
|
|
57
96
|
return text
|
|
97
|
+
elif isinstance(o, np.integer):
|
|
98
|
+
return int(o)
|
|
99
|
+
elif isinstance(o, np.floating):
|
|
100
|
+
return float(o)
|
|
101
|
+
elif isinstance(o, np.ndarray):
|
|
102
|
+
return o.tolist()
|
|
58
103
|
else:
|
|
59
104
|
return super().default(o)
|
|
60
105
|
|
|
@@ -138,11 +183,16 @@ def ask_for_confirmation(main_title, second_text, parent=None):
|
|
|
138
183
|
return (out == Gtk.ResponseType.OK)
|
|
139
184
|
|
|
140
185
|
|
|
141
|
-
class TextEntry(
|
|
186
|
+
class TextEntry(GObject.GObject):
|
|
142
187
|
"""Create a Gtk text entry/view object."""
|
|
188
|
+
__gsignals__ = {
|
|
189
|
+
"text_changed": (GObject.SIGNAL_RUN_FIRST, None, (str,))
|
|
190
|
+
}
|
|
143
191
|
|
|
144
|
-
def __init__(self, n_lines=1):
|
|
192
|
+
def __init__(self, n_lines=1, small=False):
|
|
145
193
|
"""Init."""
|
|
194
|
+
GObject.GObject.__init__(self)
|
|
195
|
+
self.tmp_txt = ""
|
|
146
196
|
self.nlines = n_lines
|
|
147
197
|
if self.nlines > 1:
|
|
148
198
|
self.widget = Gtk.Frame()
|
|
@@ -156,9 +206,31 @@ class TextEntry(object):
|
|
|
156
206
|
scrolled.add(self.entry)
|
|
157
207
|
|
|
158
208
|
else:
|
|
159
|
-
|
|
209
|
+
if small:
|
|
210
|
+
self.widget = new_small_text_entry()
|
|
211
|
+
else:
|
|
212
|
+
self.widget = Gtk.Entry()
|
|
213
|
+
|
|
214
|
+
self.widget.connect("focus-in-event", self.on_enter)
|
|
215
|
+
self.widget.connect("focus-out-event", self.on_leave)
|
|
216
|
+
|
|
160
217
|
self.entry = self.widget
|
|
161
218
|
|
|
219
|
+
def do_my_signal(self, *args):
|
|
220
|
+
"""Signal handler."""
|
|
221
|
+
pass
|
|
222
|
+
|
|
223
|
+
def on_enter(self, *args):
|
|
224
|
+
"""On enter."""
|
|
225
|
+
self.tmp_txt = self.widget.get_text().strip()
|
|
226
|
+
return False
|
|
227
|
+
|
|
228
|
+
def on_leave(self, *args):
|
|
229
|
+
"""On leave."""
|
|
230
|
+
val = self.widget.get_text().strip()
|
|
231
|
+
if val != self.tmp_txt:
|
|
232
|
+
self.emit("text_changed", val)
|
|
233
|
+
|
|
162
234
|
def get_text(self):
|
|
163
235
|
"""Return the text."""
|
|
164
236
|
if self.nlines > 1:
|
|
@@ -170,6 +242,13 @@ class TextEntry(object):
|
|
|
170
242
|
else:
|
|
171
243
|
return self.entry.get_text()
|
|
172
244
|
|
|
245
|
+
def set_text(self, text):
|
|
246
|
+
"""Sets text."""
|
|
247
|
+
if self.nlines > 1:
|
|
248
|
+
self.entry.get_buffer().set_text(text)
|
|
249
|
+
else:
|
|
250
|
+
self.entry.set_text(text)
|
|
251
|
+
|
|
173
252
|
|
|
174
253
|
def get_a_value(main_title, second_text=None, is_tv=False, parent=None):
|
|
175
254
|
"""Open a dialog to get a value.
|
|
@@ -216,7 +295,7 @@ def get_a_value(main_title, second_text=None, is_tv=False, parent=None):
|
|
|
216
295
|
return out
|
|
217
296
|
|
|
218
297
|
|
|
219
|
-
def get_a_list_of_values(main_title, labels, second_text=None, parent=None):
|
|
298
|
+
def get_a_list_of_values(main_title, labels, defaults=None, second_text=None, parent=None):
|
|
220
299
|
"""Get a list of values.
|
|
221
300
|
|
|
222
301
|
Args:
|
|
@@ -224,6 +303,7 @@ def get_a_list_of_values(main_title, labels, second_text=None, parent=None):
|
|
|
224
303
|
main_title: Main title for window
|
|
225
304
|
labels: List of labes to get the values. If the label ends with /v
|
|
226
305
|
then a TextView will be shown instead of a TextEntry.
|
|
306
|
+
defaults (optional): default values-
|
|
227
307
|
second_text (optional): Second title for window-. Defaults to None.
|
|
228
308
|
|
|
229
309
|
Returns
|
|
@@ -252,7 +332,7 @@ def get_a_list_of_values(main_title, labels, second_text=None, parent=None):
|
|
|
252
332
|
is_text_view = []
|
|
253
333
|
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
254
334
|
area.pack_start(vbox, False, True, 0)
|
|
255
|
-
for txt in labels:
|
|
335
|
+
for i, txt in enumerate(labels):
|
|
256
336
|
use_tv = False
|
|
257
337
|
if txt.endswith("/v"):
|
|
258
338
|
is_text_view.append(True)
|
|
@@ -266,6 +346,11 @@ def get_a_list_of_values(main_title, labels, second_text=None, parent=None):
|
|
|
266
346
|
vbox.pack_start(lbl, False, False, 0)
|
|
267
347
|
|
|
268
348
|
entry = TextEntry(3 if use_tv else -1)
|
|
349
|
+
try:
|
|
350
|
+
entry.set_text(defaults[i])
|
|
351
|
+
except Exception:
|
|
352
|
+
pass
|
|
353
|
+
|
|
269
354
|
vbox.pack_start(entry.widget, False, False, 0)
|
|
270
355
|
entries.append(entry)
|
|
271
356
|
|
|
@@ -301,11 +386,70 @@ def add_button_to_container(box, label, tooltip=None, callback=None):
|
|
|
301
386
|
|
|
302
387
|
box.pack_start(btn, True, False, 0)
|
|
303
388
|
|
|
389
|
+
return btn
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
class MessagePanel(object):
|
|
393
|
+
"""Encapsulates a TExtView object to show messages."""
|
|
394
|
+
|
|
395
|
+
def __init__(self, size=100):
|
|
396
|
+
"""Initializarion."""
|
|
397
|
+
self.frame = None
|
|
398
|
+
self.text_view = Gtk.TextView()
|
|
399
|
+
self.textbuffer = self.text_view.get_buffer()
|
|
400
|
+
|
|
401
|
+
self.__create_message_panel(size)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def __create_message_panel(self, size):
|
|
405
|
+
"""Creates a message panel within a frame.
|
|
406
|
+
|
|
407
|
+
Args:
|
|
408
|
+
size: size of the panel
|
|
409
|
+
|
|
410
|
+
Returns
|
|
411
|
+
Gtk.TextBuffer, Gtk.Frame
|
|
412
|
+
"""
|
|
413
|
+
frame = Gtk.Frame()
|
|
414
|
+
frame.set_shadow_type(Gtk.ShadowType.IN)
|
|
415
|
+
|
|
416
|
+
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
417
|
+
box.set_size_request(-1, size)
|
|
418
|
+
frame.add(box)
|
|
419
|
+
|
|
420
|
+
# The title for the tet view
|
|
421
|
+
box.pack_start(Gtk.Label(label="Messages"), False, True, 0)
|
|
422
|
+
|
|
423
|
+
# A scroll window with the text view
|
|
424
|
+
scrolled = Gtk.ScrolledWindow()
|
|
425
|
+
scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
|
426
|
+
scrolled.add(self.text_view)
|
|
427
|
+
box.pack_start(scrolled, True, True, 0)
|
|
428
|
+
self.frame = frame
|
|
429
|
+
|
|
430
|
+
def scroll_to_end(self):
|
|
431
|
+
"""Scrolls text view to end."""
|
|
432
|
+
end = self.textbuffer.get_end_iter()
|
|
433
|
+
self.text_view.scroll_to_iter(end, 0, False, 0, 0)
|
|
434
|
+
|
|
435
|
+
def write_message(self, text):
|
|
436
|
+
"""Writes text to Text Viewer."""
|
|
437
|
+
nlines = self.textbuffer.get_line_count()
|
|
438
|
+
if nlines > 100:
|
|
439
|
+
start = self.textbuffer.get_iter_at_line(0)
|
|
440
|
+
end = self.textbuffer.get_iter_at_line(75)
|
|
441
|
+
self.textbuffer.delete(start, end)
|
|
442
|
+
|
|
443
|
+
end = self.textbuffer.get_end_iter()
|
|
444
|
+
msg = "[{}] {}".format(time.strftime("%d/%m/%y %T"), text)
|
|
445
|
+
self.textbuffer.insert(end, msg)
|
|
446
|
+
GLib.idle_add(self.scroll_to_end)
|
|
447
|
+
|
|
304
448
|
|
|
305
449
|
class ITkDBWindow(Gtk.Window):
|
|
306
450
|
"""Base class for GUI main windows."""
|
|
307
451
|
|
|
308
|
-
def __init__(self, title="", session=None, show_search=None, gtk_runs=True):
|
|
452
|
+
def __init__(self, title="", session=None, show_search=None, gtk_runs=True, panel_size=100):
|
|
309
453
|
"""Initialization.
|
|
310
454
|
|
|
311
455
|
Args:
|
|
@@ -321,12 +465,13 @@ class ITkDBWindow(Gtk.Window):
|
|
|
321
465
|
self.session = session
|
|
322
466
|
self.inst2code = {}
|
|
323
467
|
self.code2inst = {}
|
|
468
|
+
self.message_panel = None
|
|
324
469
|
|
|
325
470
|
if gtk_runs:
|
|
326
471
|
super().__init__(title=title)
|
|
327
|
-
self.prepare_window(show_search)
|
|
472
|
+
self.prepare_window(show_search, panel_size)
|
|
328
473
|
|
|
329
|
-
def prepare_window(self, show_search):
|
|
474
|
+
def prepare_window(self, show_search, panel_size):
|
|
330
475
|
"""Inititalizes GUI."""
|
|
331
476
|
# Prepare HeaderBar
|
|
332
477
|
self.hb = Gtk.HeaderBar()
|
|
@@ -351,11 +496,13 @@ class ITkDBWindow(Gtk.Window):
|
|
|
351
496
|
|
|
352
497
|
# Create main content box
|
|
353
498
|
self.mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
499
|
+
self.mainBox.set_property("margin-left", 6)
|
|
500
|
+
self.mainBox.set_property("margin-right", 6)
|
|
501
|
+
|
|
354
502
|
self.add(self.mainBox)
|
|
355
503
|
|
|
356
504
|
# The text view and buffer
|
|
357
|
-
self.
|
|
358
|
-
self.textbuffer = self.text_view.get_buffer()
|
|
505
|
+
self.message_panel = MessagePanel(size=panel_size)
|
|
359
506
|
|
|
360
507
|
# The button box
|
|
361
508
|
btnBox = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL)
|
|
@@ -378,7 +525,8 @@ class ITkDBWindow(Gtk.Window):
|
|
|
378
525
|
def new_login(self, obj, msg):
|
|
379
526
|
"""A new user logged in."""
|
|
380
527
|
if msg == "<OK>":
|
|
381
|
-
self.session
|
|
528
|
+
if hasattr(self.session, "user_gui"):
|
|
529
|
+
self.session = self.session.user_gui.get_client()
|
|
382
530
|
self.userLabel.get_child().set_text(self.session.user.name)
|
|
383
531
|
|
|
384
532
|
else:
|
|
@@ -450,29 +598,15 @@ class ITkDBWindow(Gtk.Window):
|
|
|
450
598
|
|
|
451
599
|
return frame
|
|
452
600
|
|
|
453
|
-
def scroll_to_end(self):
|
|
454
|
-
"""Scrolls text view to end."""
|
|
455
|
-
end = self.textbuffer.get_end_iter()
|
|
456
|
-
self.text_view.scroll_to_iter(end, 0, False, 0, 0)
|
|
457
|
-
|
|
458
601
|
def write_message(self, text):
|
|
459
602
|
"""Writes text to Text Viewer."""
|
|
460
|
-
|
|
461
|
-
if nlines > 100:
|
|
462
|
-
start = self.textbuffer.get_iter_at_line(0)
|
|
463
|
-
end = self.textbuffer.get_iter_at_line(75)
|
|
464
|
-
self.textbuffer.delete(start, end)
|
|
465
|
-
|
|
466
|
-
end = self.textbuffer.get_end_iter()
|
|
467
|
-
msg = "[{}] {}".format(time.strftime("%d/%m/%y %T"), text)
|
|
468
|
-
self.textbuffer.insert(end, msg)
|
|
469
|
-
GLib.idle_add(self.scroll_to_end)
|
|
603
|
+
self.message_panel.write_message(text)
|
|
470
604
|
|
|
471
605
|
|
|
472
606
|
class DictDialog(Gtk.Grid):
|
|
473
607
|
"""Creates a dialog to show and edit variables in a JSon dict."""
|
|
474
608
|
|
|
475
|
-
def __init__(self, values, hidden_keys=
|
|
609
|
+
def __init__(self, values, hidden_keys=None):
|
|
476
610
|
"""Create the Gtk.Grid.
|
|
477
611
|
|
|
478
612
|
Args:
|
|
@@ -484,12 +618,18 @@ class DictDialog(Gtk.Grid):
|
|
|
484
618
|
super().__init__(column_spacing=5, row_spacing=1)
|
|
485
619
|
|
|
486
620
|
self.set_border_width(10)
|
|
621
|
+
self.factory = deepcopy(values)
|
|
487
622
|
self.values = deepcopy(values)
|
|
488
623
|
self.keys = {}
|
|
489
624
|
self.containers = {}
|
|
490
|
-
self.hidden_keys = hidden_keys
|
|
625
|
+
self.hidden_keys = hidden_keys if hidden_keys else {}
|
|
491
626
|
self.show_values()
|
|
492
627
|
|
|
628
|
+
def factory_reset(self):
|
|
629
|
+
"""Set values to original values."""
|
|
630
|
+
self.values = deepcopy(self.factory)
|
|
631
|
+
self.refresh()
|
|
632
|
+
|
|
493
633
|
def on_enter(self, entry, *args):
|
|
494
634
|
"""Get the value when we first enter into the Entry."""
|
|
495
635
|
self.keys[args[2]] = entry.get_text()
|
|
@@ -519,6 +659,15 @@ class DictDialog(Gtk.Grid):
|
|
|
519
659
|
elif isinstance(itm[last_key], datetime):
|
|
520
660
|
itm[last_key] = dateutil.parser.parse(txt)
|
|
521
661
|
|
|
662
|
+
elif is_a_date(itm[last_key]):
|
|
663
|
+
D = dateutil.parser.parse(txt)
|
|
664
|
+
out = D.isoformat(timespec='milliseconds')
|
|
665
|
+
if out[-1] not in ['zZ']:
|
|
666
|
+
out += 'Z'
|
|
667
|
+
|
|
668
|
+
itm[last_key] = out
|
|
669
|
+
self.containers[name].set_text(out)
|
|
670
|
+
|
|
522
671
|
else:
|
|
523
672
|
tp = type(itm[last_key])
|
|
524
673
|
itm[last_key] = tp(txt)
|
itkdb_gtk/readAVSdata.py
CHANGED
|
@@ -5,10 +5,14 @@ from argparse import ArgumentParser
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
|
|
7
7
|
try:
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
except
|
|
11
|
-
from
|
|
8
|
+
import itkdb_gtk
|
|
9
|
+
|
|
10
|
+
except ImportError:
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
cwd = Path(sys.argv[0]).parent.parent
|
|
13
|
+
sys.path.append(cwd.as_posix())
|
|
14
|
+
|
|
15
|
+
from itkdb_gtk import ITkDBlogin, ITkDButils
|
|
12
16
|
|
|
13
17
|
import dateutil.parser
|
|
14
18
|
import openpyxl as XL
|
itkdb_gtk/readGoogleSheet.py
CHANGED
|
@@ -13,7 +13,7 @@ SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly']
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
# Get spreadsheet ID from share link
|
|
16
|
-
re_sheet_id = re.compile(r"https://docs.google.com/spreadsheets/d/(?P<ID
|
|
16
|
+
re_sheet_id = re.compile(r"https://docs.google.com/spreadsheets/d/(?P<ID>[\w-]+)", re.DOTALL)
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
def get_spreadsheet_service():
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Un trash a trashed component."""
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def untrash_component(client, SN, reason="Accidentally trashed"):
|
|
6
|
+
"""Un trash given component.
|
|
7
|
+
|
|
8
|
+
Args:
|
|
9
|
+
SN (str): Serial number of component to recover.
|
|
10
|
+
reason (str): message for the DB
|
|
11
|
+
Return:
|
|
12
|
+
dict: PDB response.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
DTO = {
|
|
16
|
+
'component': SN,
|
|
17
|
+
'trashed': False,
|
|
18
|
+
'reason': reason
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
response = client.post('setComponentTrashed', json=DTO)
|
|
22
|
+
return response
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
import sys
|
|
27
|
+
from itkdb_gtk import ITkDBlogin
|
|
28
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
29
|
+
client = dlg.get_client()
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
response = untrash_component(client, sys.argv[1])
|
|
33
|
+
|
|
34
|
+
except Exception as E:
|
|
35
|
+
print(str(E))
|