itkdb-gtk 0.10.7__tar.gz → 0.10.9.dev1__tar.gz
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-0.10.7 → itkdb_gtk-0.10.9.dev1}/PKG-INFO +1 -1
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/CreateShipments.py +7 -3
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ITkDBlogin.py +2 -2
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ITkDButils.py +20 -1
- itkdb_gtk-0.10.9.dev1/itkdb_gtk/PanelVisualInspection.py +405 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/PetalReceptionTests.py +33 -23
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/UploadMultipleTests.py +1 -1
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/WireBondGui.py +1 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/__init__.py +6 -1
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/dashBoard.py +24 -2
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/dbGtkUtils.py +39 -12
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/PKG-INFO +1 -1
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/SOURCES.txt +1 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/entry_points.txt +1 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/pyproject.toml +2 -1
- itkdb_gtk-0.10.9.dev1/test/test_attachment.py +70 -0
- itkdb_gtk-0.10.7/itkdb_gtk/PanelVisualInspection.py +0 -230
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/README.md +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/GetShipments.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/GlueWeight.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ITkDB.desktop +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ITkDB.svg +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/SensorUtils.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ShowAttachments.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ShowComments.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/ShowDefects.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/UploadModuleIV.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/UploadPetalInformation.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/UploadTest.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/readAVSdata.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/readGoogleSheet.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk/untrash_component.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/dependency_links.txt +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/requires.txt +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/itkdb_gtk.egg-info/top_level.txt +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/setup.cfg +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/test/testAnimated.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/test/testComponent.py +0 -0
- {itkdb_gtk-0.10.7 → itkdb_gtk-0.10.9.dev1}/test/test_holes.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itkdb_gtk
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.9.dev1
|
|
4
4
|
Summary: A collection of Gtk based GUI to access ITkDB.
|
|
5
5
|
Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
|
|
@@ -28,7 +28,7 @@ gtk_runs, gtk_args = Gtk.init_check()
|
|
|
28
28
|
class CreateShipments(dbGtkUtils.ITkDBWindow):
|
|
29
29
|
"""Create a shipment from input."""
|
|
30
30
|
|
|
31
|
-
def __init__(self, session):
|
|
31
|
+
def __init__(self, session, help=None):
|
|
32
32
|
"""Initialization.
|
|
33
33
|
|
|
34
34
|
Args:
|
|
@@ -41,7 +41,7 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
|
|
|
41
41
|
self.attachment = None
|
|
42
42
|
global gtk_runs
|
|
43
43
|
if gtk_runs:
|
|
44
|
-
super().__init__(session=session, title="Upload AVS Data", gtk_runs=gtk_runs)
|
|
44
|
+
super().__init__(session=session, title="Upload AVS Data", help=help, gtk_runs=gtk_runs)
|
|
45
45
|
self.init_window()
|
|
46
46
|
|
|
47
47
|
def init_window(self):
|
|
@@ -193,10 +193,14 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
|
|
|
193
193
|
dbGtkUtils.complain("Item {} is already in transit".format(SN),
|
|
194
194
|
"This item is already in transit to {}".format(rc['shipmentDestination']['code']))
|
|
195
195
|
return
|
|
196
|
+
|
|
196
197
|
nick = rc['alternativeIdentifier']
|
|
197
198
|
id = rc['id']
|
|
198
199
|
obj = rc['componentType']['name']
|
|
199
200
|
loc = rc['currentLocation']['code']
|
|
201
|
+
serialN = rc['serialNumber']
|
|
202
|
+
if serialN is None:
|
|
203
|
+
serialN = id
|
|
200
204
|
|
|
201
205
|
# Check tha tthe input is not already there
|
|
202
206
|
model = self.tree.get_model()
|
|
@@ -210,7 +214,7 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
|
|
|
210
214
|
iter = model.iter_next(iter)
|
|
211
215
|
|
|
212
216
|
# Add the item in the liststore.
|
|
213
|
-
model.append([
|
|
217
|
+
model.append([serialN, nick, obj, loc, id])
|
|
214
218
|
|
|
215
219
|
except Exception:
|
|
216
220
|
dbGtkUtils.complain("Error querying DB",
|
|
@@ -306,12 +306,12 @@ class ITkDBlogin(Gtk.Dialog):
|
|
|
306
306
|
# token_file.write(json.dumps(self.token))
|
|
307
307
|
self.hide()
|
|
308
308
|
|
|
309
|
-
def get_client(self):
|
|
309
|
+
def get_client(self, use_eos=True):
|
|
310
310
|
"""Return the client."""
|
|
311
311
|
if not self.is_connected():
|
|
312
312
|
return None
|
|
313
313
|
|
|
314
|
-
return itkdb.Client(user=self.user)
|
|
314
|
+
return itkdb.Client(user=self.user, use_eos=use_eos)
|
|
315
315
|
|
|
316
316
|
def __del__(self):
|
|
317
317
|
"""Delete."""
|
|
@@ -3,8 +3,10 @@ import mimetypes
|
|
|
3
3
|
from collections.abc import Iterable
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
import getpass
|
|
6
7
|
|
|
7
8
|
import dateutil.parser
|
|
9
|
+
import itkdb
|
|
8
10
|
|
|
9
11
|
# The response of the DB
|
|
10
12
|
db_response = ""
|
|
@@ -281,6 +283,7 @@ def upload_test(client, data, attachments=None):
|
|
|
281
283
|
db_response = client.post('createTestRunAttachment',
|
|
282
284
|
data=data,
|
|
283
285
|
files=attachment)
|
|
286
|
+
|
|
284
287
|
|
|
285
288
|
return None
|
|
286
289
|
|
|
@@ -453,7 +456,7 @@ def get_testrun(session, test_id, out_type="object"):
|
|
|
453
456
|
return None
|
|
454
457
|
|
|
455
458
|
|
|
456
|
-
def get_test_skeleton(session, component, test_code, userdef=
|
|
459
|
+
def get_test_skeleton(session, component, test_code, userdef=None, uservalues=None):
|
|
457
460
|
"""Get the skeleton of the given test.
|
|
458
461
|
|
|
459
462
|
Args:
|
|
@@ -465,6 +468,13 @@ def get_test_skeleton(session, component, test_code, userdef={}, uservalues={}):
|
|
|
465
468
|
|
|
466
469
|
"""
|
|
467
470
|
global db_response
|
|
471
|
+
|
|
472
|
+
if userdef is None:
|
|
473
|
+
userdef = {}
|
|
474
|
+
|
|
475
|
+
if uservalues is None:
|
|
476
|
+
uservalues = {}
|
|
477
|
+
|
|
468
478
|
defvalues = {
|
|
469
479
|
"string": "",
|
|
470
480
|
"integer": -9999,
|
|
@@ -550,3 +560,12 @@ def get_test_skeleton(session, component, test_code, userdef={}, uservalues={}):
|
|
|
550
560
|
skltn['results'][key] = get_default(par)
|
|
551
561
|
|
|
552
562
|
return skltn
|
|
563
|
+
|
|
564
|
+
def create_client():
|
|
565
|
+
"""Create a Client."""
|
|
566
|
+
client = itkdb.Client()
|
|
567
|
+
client.user._access_code1 = getpass.getpass("Access 1: ")
|
|
568
|
+
client.user._access_code2 = getpass.getpass("Access 2: ")
|
|
569
|
+
client.user.authenticate()
|
|
570
|
+
print("Hello {} !".format(client.user.name))
|
|
571
|
+
return client
|
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""PB/Hybrid panel Visual inspection GUI.."""
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
import copy
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
try:
|
|
9
|
+
import itkdb_gtk
|
|
10
|
+
|
|
11
|
+
except ImportError:
|
|
12
|
+
cwd = Path(__file__).parent.parent
|
|
13
|
+
sys.path.append(cwd.as_posix())
|
|
14
|
+
|
|
15
|
+
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
|
|
16
|
+
from itkdb_gtk.ShowComments import ShowComments
|
|
17
|
+
from itkdb_gtk.ShowDefects import ShowDefects
|
|
18
|
+
from itkdb_gtk.UploadTest import create_json_data_editor
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
import gi
|
|
23
|
+
gi.require_version("Gtk", "3.0")
|
|
24
|
+
from gi.repository import Gtk, Gdk, Gio, GObject
|
|
25
|
+
|
|
26
|
+
HELP_LINK="https://itkdb-gtk.docs.cern.ch"
|
|
27
|
+
|
|
28
|
+
class TestJson(GObject.Object):
|
|
29
|
+
"""To store test JSOn."""
|
|
30
|
+
__gtype_name__ = "TestJson"
|
|
31
|
+
|
|
32
|
+
def __init__(self, js=None):
|
|
33
|
+
super().__init__()
|
|
34
|
+
self.js = copy.deepcopy(js)
|
|
35
|
+
|
|
36
|
+
def set_js(self, js):
|
|
37
|
+
"""SEts the dictionary"""
|
|
38
|
+
self.js = copy.deepcopy(js)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class PanelVisualInspection(dbGtkUtils.ITkDBWindow):
|
|
42
|
+
"""PB/Hybryd panel visual inspection GUI."""
|
|
43
|
+
SN, PASSED, F_NAME, F_PATH, TEST_J, ALL = range(6)
|
|
44
|
+
|
|
45
|
+
def __init__(self, session, title="PanelVisualInspection", help=HELP_LINK):
|
|
46
|
+
super().__init__(title="ITkDB Dashboard",
|
|
47
|
+
session=session,
|
|
48
|
+
show_search="Find object with given SN.",
|
|
49
|
+
help=help)
|
|
50
|
+
|
|
51
|
+
self.institute = "IFIC"
|
|
52
|
+
# action button in header
|
|
53
|
+
button = Gtk.Button()
|
|
54
|
+
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
55
|
+
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
56
|
+
button.add(image)
|
|
57
|
+
button.set_tooltip_text("Click to upload ALL tests.")
|
|
58
|
+
button.connect("clicked", self.upload_tests)
|
|
59
|
+
self.hb.pack_end(button)
|
|
60
|
+
|
|
61
|
+
grid = Gtk.Grid(column_spacing=5, row_spacing=1)
|
|
62
|
+
self.mainBox.pack_start(grid, False, False, 5)
|
|
63
|
+
|
|
64
|
+
irow = 0
|
|
65
|
+
receiver = self.create_institute_combo()
|
|
66
|
+
receiver.connect("changed", self.on_institute)
|
|
67
|
+
receiver.set_tooltip_text("Select the Institute making the test.")
|
|
68
|
+
dbGtkUtils.set_combo_iter(receiver, self.institute)
|
|
69
|
+
grid.attach(Gtk.Label(label="Institute"), 0, irow, 1, 1)
|
|
70
|
+
grid.attach(receiver, 1, irow, 1, 1)
|
|
71
|
+
|
|
72
|
+
irow += 1
|
|
73
|
+
lbl = Gtk.Label(label="Serial Number")
|
|
74
|
+
lbl.set_xalign(0)
|
|
75
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
76
|
+
|
|
77
|
+
self.SN = dbGtkUtils.TextEntry(small=True)
|
|
78
|
+
self.SN.connect("text_changed", self.SN_ready)
|
|
79
|
+
self.SN.widget.set_tooltip_text("Enter SN of PWD or Hybrid panel.")
|
|
80
|
+
grid.attach(self.SN.widget, 1, irow, 1, 1)
|
|
81
|
+
|
|
82
|
+
self.panel_type = Gtk.Label(label="")
|
|
83
|
+
grid.attach(self.panel_type, 2, irow, 1, 1)
|
|
84
|
+
|
|
85
|
+
irow += 1
|
|
86
|
+
lbl = Gtk.Label(label="Date")
|
|
87
|
+
lbl.set_xalign(0)
|
|
88
|
+
grid.attach(lbl, 0, irow, 1, 1)
|
|
89
|
+
|
|
90
|
+
self.date = dbGtkUtils.TextEntry(small=True)
|
|
91
|
+
grid.attach(self.date.widget, 1, irow, 1, 1)
|
|
92
|
+
self.date.entry.set_text(ITkDButils.get_db_date())
|
|
93
|
+
self.date.connect("text_changed", self.new_date)
|
|
94
|
+
|
|
95
|
+
# Paned object
|
|
96
|
+
paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
|
97
|
+
paned.set_size_request(-1, 200)
|
|
98
|
+
self.mainBox.pack_start(paned, True, True, 5)
|
|
99
|
+
|
|
100
|
+
# the list of attachments
|
|
101
|
+
tree_view = self.create_tree_view()
|
|
102
|
+
paned.add1(tree_view)
|
|
103
|
+
|
|
104
|
+
# The text view
|
|
105
|
+
paned.add2(self.message_panel.frame)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
self.show_all()
|
|
109
|
+
|
|
110
|
+
dbGtkUtils.setup_scanner(self.get_qrcode)
|
|
111
|
+
|
|
112
|
+
def on_institute(self, combo):
|
|
113
|
+
"""A new recipient has been chosen."""
|
|
114
|
+
name = self.get_institute_from_combo(combo)
|
|
115
|
+
if name:
|
|
116
|
+
self.institute = name
|
|
117
|
+
|
|
118
|
+
def new_date(self, entry, value):
|
|
119
|
+
"""new date given at input."""
|
|
120
|
+
d = dbGtkUtils.parse_date_as_string(value)
|
|
121
|
+
if d is not None:
|
|
122
|
+
self.date.set_text(d)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def create_model(self):
|
|
126
|
+
"""Create tree view model."""
|
|
127
|
+
return Gtk.ListStore(str, bool, str, str, TestJson)
|
|
128
|
+
|
|
129
|
+
def create_tree_view(self, size=150):
|
|
130
|
+
"""Create the TreeView with the children."""
|
|
131
|
+
model = self.create_model()
|
|
132
|
+
self.tree = Gtk.TreeView(model=model)
|
|
133
|
+
self.tree.connect("button-press-event", self.button_pressed)
|
|
134
|
+
|
|
135
|
+
scrolled = Gtk.ScrolledWindow()
|
|
136
|
+
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
|
137
|
+
scrolled.add(self.tree)
|
|
138
|
+
scrolled.set_size_request(-1, size)
|
|
139
|
+
|
|
140
|
+
renderer = Gtk.CellRendererText()
|
|
141
|
+
column = Gtk.TreeViewColumn("SN", renderer, text=PanelVisualInspection.SN)
|
|
142
|
+
self.tree.append_column(column)
|
|
143
|
+
|
|
144
|
+
renderer = Gtk.CellRendererToggle()
|
|
145
|
+
renderer.set_property("activatable", True)
|
|
146
|
+
renderer.set_property("radio", True)
|
|
147
|
+
renderer.set_padding(5, 0)
|
|
148
|
+
|
|
149
|
+
x, y = renderer.get_alignment()
|
|
150
|
+
renderer.set_alignment(0, y)
|
|
151
|
+
# renderer.set_property("inconsistent", True)
|
|
152
|
+
renderer.connect("toggled", self.btn_toggled)
|
|
153
|
+
|
|
154
|
+
column = Gtk.TreeViewColumn("Passed", renderer, active=PanelVisualInspection.PASSED)
|
|
155
|
+
self.tree.append_column(column)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
renderer = Gtk.CellRendererText()
|
|
159
|
+
column = Gtk.TreeViewColumn("Image", renderer, text=PanelVisualInspection.F_NAME)
|
|
160
|
+
self.tree.append_column(column)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
return scrolled
|
|
164
|
+
|
|
165
|
+
def btn_toggled(self, renderer, path, *args):
|
|
166
|
+
"""Toggled."""
|
|
167
|
+
model = self.tree.get_model()
|
|
168
|
+
val = not model[path][PanelVisualInspection.PASSED]
|
|
169
|
+
model[path][PanelVisualInspection.PASSED] = val
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def button_pressed(self, tree, event):
|
|
173
|
+
"""Button pressed on tree view."""
|
|
174
|
+
# double click shows attachments
|
|
175
|
+
if event.button == 1 and event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
|
|
176
|
+
self.write_message("This is a double click.\n")
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
if event.button != 3:
|
|
180
|
+
return
|
|
181
|
+
|
|
182
|
+
# Create popup menu
|
|
183
|
+
select = self.tree.get_selection()
|
|
184
|
+
model, iter = select.get_selected()
|
|
185
|
+
values = None
|
|
186
|
+
if iter:
|
|
187
|
+
values = model[iter]
|
|
188
|
+
|
|
189
|
+
if not iter:
|
|
190
|
+
P = tree.get_path_at_pos(event.x, event.y)
|
|
191
|
+
if P:
|
|
192
|
+
print(P[0].to_string())
|
|
193
|
+
iter = model.get_iter(P[0])
|
|
194
|
+
values = model[iter]
|
|
195
|
+
|
|
196
|
+
if not values:
|
|
197
|
+
return
|
|
198
|
+
|
|
199
|
+
menu = Gtk.Menu()
|
|
200
|
+
|
|
201
|
+
item_show = Gtk.MenuItem(label="Upload Image")
|
|
202
|
+
item_show.connect("activate", self.on_upload_image, (model, iter, values))
|
|
203
|
+
menu.append(item_show)
|
|
204
|
+
|
|
205
|
+
item_show_json = Gtk.MenuItem(label="Show JSOn")
|
|
206
|
+
item_show_json.connect("activate", self.on_show_json, (model, iter, values))
|
|
207
|
+
menu.append(item_show_json)
|
|
208
|
+
|
|
209
|
+
item_show_com = Gtk.MenuItem(label="Edit Comments")
|
|
210
|
+
item_show_com.connect("activate", self.on_show_comments, (model, iter, values))
|
|
211
|
+
menu.append(item_show_com)
|
|
212
|
+
|
|
213
|
+
item_show_def = Gtk.MenuItem(label="Edit Defects")
|
|
214
|
+
item_show_def.connect("activate", self.on_show_defects, (model, iter, values))
|
|
215
|
+
menu.append(item_show_def)
|
|
216
|
+
|
|
217
|
+
menu.show_all()
|
|
218
|
+
menu.popup_at_pointer(event)
|
|
219
|
+
|
|
220
|
+
def on_upload_image(self, item, data):
|
|
221
|
+
"""Choose file."""
|
|
222
|
+
fdlg = Gtk.FileChooserNative(action=Gtk.FileChooserAction.OPEN, accept_label="Select")
|
|
223
|
+
response = fdlg.run()
|
|
224
|
+
if response == Gtk.ResponseType.ACCEPT:
|
|
225
|
+
ifiles = [ipath for ipath in fdlg.get_filenames()]
|
|
226
|
+
if len(ifiles)<1:
|
|
227
|
+
return
|
|
228
|
+
|
|
229
|
+
if len(ifiles) > 1:
|
|
230
|
+
dbGtkUtils.complain("More than one file selected","Choosing first.")
|
|
231
|
+
|
|
232
|
+
fnam = ifiles[0]
|
|
233
|
+
model, iter, val = data
|
|
234
|
+
model.set_value(iter, PanelVisualInspection.F_PATH, fnam)
|
|
235
|
+
model.set_value(iter, PanelVisualInspection.F_NAME, Path(fnam).name)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
self.write_message("Upload image\n")
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def on_show_json(self, item, data):
|
|
242
|
+
"""Test JSon."""
|
|
243
|
+
model, iter, val = data
|
|
244
|
+
payload = val[PanelVisualInspection.TEST_J].js
|
|
245
|
+
value, dlg = create_json_data_editor(payload)
|
|
246
|
+
rc = dlg.run()
|
|
247
|
+
if rc == Gtk.ResponseType.OK:
|
|
248
|
+
payload = value.values
|
|
249
|
+
model.set_value(iter, PanelVisualInspection.TEST_J, TestJson(payload))
|
|
250
|
+
|
|
251
|
+
dlg.hide()
|
|
252
|
+
dlg.destroy()
|
|
253
|
+
|
|
254
|
+
def on_show_comments(self, item, data):
|
|
255
|
+
"""Show comments"""
|
|
256
|
+
model, iter, val = data
|
|
257
|
+
js = val[PanelVisualInspection.TEST_J].js
|
|
258
|
+
SC = ShowComments("Test Comments", js["comments"], self)
|
|
259
|
+
rc = SC.run()
|
|
260
|
+
if rc == Gtk.ResponseType.OK:
|
|
261
|
+
js["comments"] = SC.comments
|
|
262
|
+
model.set_value(iter, PanelVisualInspection.TEST_J, TestJson(js))
|
|
263
|
+
|
|
264
|
+
SC.hide()
|
|
265
|
+
SC.destroy()
|
|
266
|
+
|
|
267
|
+
def on_show_defects(self, item, data):
|
|
268
|
+
"""Show comments"""
|
|
269
|
+
model, iter, val = data
|
|
270
|
+
js = val[PanelVisualInspection.TEST_J].js
|
|
271
|
+
SD = ShowDefects("Test Defects", js["defects"], self)
|
|
272
|
+
rc = SD.run()
|
|
273
|
+
if rc == Gtk.ResponseType.OK:
|
|
274
|
+
js["defects"] = SD.defects
|
|
275
|
+
model.set_value(iter, PanelVisualInspection.TEST_J, TestJson(js))
|
|
276
|
+
|
|
277
|
+
SD.hide()
|
|
278
|
+
SD.destroy()
|
|
279
|
+
|
|
280
|
+
def SN_ready(self, *args):
|
|
281
|
+
"""SN is ready in the TextEnttry."""
|
|
282
|
+
SN = self.SN.get_text()
|
|
283
|
+
# GEt children.
|
|
284
|
+
panel = ITkDButils.get_DB_component(self.session, SN)
|
|
285
|
+
if panel is None:
|
|
286
|
+
self.write_message(ITkDButils.get_db_response())
|
|
287
|
+
return
|
|
288
|
+
|
|
289
|
+
SN = panel["serialNumber"]
|
|
290
|
+
args[0].set_text(SN)
|
|
291
|
+
is_PWB = False
|
|
292
|
+
defaults = {
|
|
293
|
+
"institution": self.institute,
|
|
294
|
+
"runNumber": "1",
|
|
295
|
+
"date": self.date.get_text()
|
|
296
|
+
}
|
|
297
|
+
component_type = None
|
|
298
|
+
test_code = None
|
|
299
|
+
if "USED" in SN:
|
|
300
|
+
# Powerboard Carrier
|
|
301
|
+
if not SN[6].isdigit():
|
|
302
|
+
dbGtkUtils.complain("Not a Powerboard Carrier",
|
|
303
|
+
"{}: wrong SN for a powerboard carrier".format(SN))
|
|
304
|
+
self.SN.widget.set_text("")
|
|
305
|
+
return
|
|
306
|
+
|
|
307
|
+
self.panel_type.set_text("PWB carrier")
|
|
308
|
+
is_PWB = True
|
|
309
|
+
component_type = "PWB"
|
|
310
|
+
test_code = "PICTURE"
|
|
311
|
+
|
|
312
|
+
elif "USET" in SN:
|
|
313
|
+
# Hybrid test panel
|
|
314
|
+
component_type = "HYBRID_TEST_PANEL"
|
|
315
|
+
test_code = "VISUAL_INSPECTION_RECEPTION"
|
|
316
|
+
|
|
317
|
+
if not SN[6].isdigit or int(SN[6])>5:
|
|
318
|
+
dbGtkUtils.complain("Not a Hybrid Test Panel",
|
|
319
|
+
"{}: wrong SN for a hybrid test panel".format(SN))
|
|
320
|
+
self.SN.widget.set_text("")
|
|
321
|
+
return
|
|
322
|
+
|
|
323
|
+
self.panel_type.set_text("HYB test panel")
|
|
324
|
+
|
|
325
|
+
else:
|
|
326
|
+
dbGtkUtils.complain("Invalid SN.",
|
|
327
|
+
"{}\nNot a PWB carrier not HYB test panel.".format(SN))
|
|
328
|
+
self.SN.widget.set_text("")
|
|
329
|
+
return
|
|
330
|
+
|
|
331
|
+
# GEt children.
|
|
332
|
+
skltn = ITkDButils.get_test_skeleton(self.session, component_type, test_code, defaults)
|
|
333
|
+
model = self.create_model()
|
|
334
|
+
for child in panel["children"]:
|
|
335
|
+
if child["component"] is not None:
|
|
336
|
+
child_SN = child["component"]["serialNumber"]
|
|
337
|
+
skltn["component"] = child_SN
|
|
338
|
+
model.append([child_SN, True, "", "", TestJson(skltn)])
|
|
339
|
+
|
|
340
|
+
self.tree.set_model(model)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def upload_tests(self, *args):
|
|
344
|
+
"""Upload the current test."""
|
|
345
|
+
SN = self.SN.get_text()
|
|
346
|
+
|
|
347
|
+
model = self.tree.get_model()
|
|
348
|
+
iter = model.get_iter_first()
|
|
349
|
+
n_items = 0
|
|
350
|
+
while iter:
|
|
351
|
+
values = model[iter]
|
|
352
|
+
payload = values[PanelVisualInspection.TEST_J].js
|
|
353
|
+
ifile = values[PanelVisualInspection.F_PATH]
|
|
354
|
+
if len(ifile)>0:
|
|
355
|
+
attachments = [ITkDButils.Attachment(ifile, "Image", "Image")]
|
|
356
|
+
else:
|
|
357
|
+
attachments = []
|
|
358
|
+
|
|
359
|
+
rc = ITkDButils.upload_test(self.session, payload, attachments)
|
|
360
|
+
if rc:
|
|
361
|
+
ipos = rc.find("The following details may help:")
|
|
362
|
+
msg = rc[ipos:]
|
|
363
|
+
dbGtkUtils.complain("Failed uploading test {}-{}".format(payload["component"], payload["testType"]), msg)
|
|
364
|
+
self.write_message(msg)
|
|
365
|
+
|
|
366
|
+
else:
|
|
367
|
+
self.write_message("Upload {}-{} successfull\n".format(payload["component"], payload["testType"]))
|
|
368
|
+
|
|
369
|
+
n_items += 1
|
|
370
|
+
iter = model.iter_next(iter)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def get_qrcode(self, fd, state, reader):
|
|
374
|
+
"""Read SN from scanner."""
|
|
375
|
+
txt = dbGtkUtils.scanner_get_line(reader)
|
|
376
|
+
self.write_message("SN: {}\n".format(txt))
|
|
377
|
+
self.SN_ready(txt, self.SN.widget)
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def main():
|
|
381
|
+
"""Main entry."""
|
|
382
|
+
# DB login
|
|
383
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
384
|
+
client = dlg.get_client()
|
|
385
|
+
if client is None:
|
|
386
|
+
print("Could not connect to DB with provided credentials.")
|
|
387
|
+
dlg.die()
|
|
388
|
+
sys.exit()
|
|
389
|
+
|
|
390
|
+
client.user_gui = dlg
|
|
391
|
+
|
|
392
|
+
gTest = PanelVisualInspection(client)
|
|
393
|
+
|
|
394
|
+
gTest.present()
|
|
395
|
+
gTest.connect("destroy", Gtk.main_quit)
|
|
396
|
+
try:
|
|
397
|
+
Gtk.main()
|
|
398
|
+
|
|
399
|
+
except KeyboardInterrupt:
|
|
400
|
+
print("Arrrgggg!!!")
|
|
401
|
+
|
|
402
|
+
dlg.die()
|
|
403
|
+
|
|
404
|
+
if __name__ == "__main__":
|
|
405
|
+
main()
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Test dashboard."""
|
|
3
|
-
import json
|
|
4
3
|
import sys
|
|
4
|
+
import copy
|
|
5
|
+
from pathlib import Path
|
|
5
6
|
|
|
6
7
|
try:
|
|
7
8
|
import itkdb_gtk
|
|
8
|
-
|
|
9
|
+
|
|
9
10
|
except ImportError:
|
|
10
|
-
from pathlib import Path
|
|
11
11
|
cwd = Path(__file__).parent.parent
|
|
12
12
|
sys.path.append(cwd.as_posix())
|
|
13
|
+
import itkdb_gtk
|
|
13
14
|
|
|
14
15
|
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
|
|
15
16
|
|
|
@@ -66,7 +67,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
66
67
|
|
|
67
68
|
self.SN = itkdb_gtk.dbGtkUtils.TextEntry()
|
|
68
69
|
self.SN.connect("text-changed", self.on_SN_changed)
|
|
69
|
-
|
|
70
|
+
|
|
70
71
|
#self.SN = Gtk.Entry()
|
|
71
72
|
#self.SN.connect("focus-in-event", self.on_sn_enter)
|
|
72
73
|
#self.SN.connect("focus-out-event", self.on_sn_leave)
|
|
@@ -107,6 +108,8 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
107
108
|
self.create_test_box("Visual Inspection", "VISUAL_INSPECTION")
|
|
108
109
|
self.create_test_box("Grounding", "GROUNDING_CHECK")
|
|
109
110
|
self.create_test_box("Pipe bending", "BENDING120")
|
|
111
|
+
self.create_test_box("X-rays", "XRAYIMAGING")
|
|
112
|
+
|
|
110
113
|
|
|
111
114
|
# The text view
|
|
112
115
|
self.mainBox.pack_end(self.message_panel.frame, True, True, 5)
|
|
@@ -117,7 +120,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
117
120
|
"""New SN given. Ask in PDB,"""
|
|
118
121
|
if len(value) <= 0:
|
|
119
122
|
return None
|
|
120
|
-
|
|
123
|
+
|
|
121
124
|
self.query_db()
|
|
122
125
|
current_location = self.dbObject["currentLocation"]["code"]
|
|
123
126
|
dbGtkUtils.set_combo_iter(self.inst_cmb, current_location, 0)
|
|
@@ -134,7 +137,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
134
137
|
for i in range(npages):
|
|
135
138
|
page = self.notebook.get_nth_page(i)
|
|
136
139
|
page.dict_dialog.factory_reset()
|
|
137
|
-
|
|
140
|
+
|
|
138
141
|
|
|
139
142
|
def create_test_box(self, label, test_name, institute="IFIC"):
|
|
140
143
|
"""Create and add to notebook a test dialog.
|
|
@@ -213,6 +216,27 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
213
216
|
page.dict_dialog.values["institution"] = self.institute
|
|
214
217
|
page.dict_dialog.refresh()
|
|
215
218
|
|
|
219
|
+
def upload_this_test(self, values):
|
|
220
|
+
"""Upload a single test."""
|
|
221
|
+
# print(json.dumps(values, indent=2))
|
|
222
|
+
|
|
223
|
+
attachments = []
|
|
224
|
+
if values["testType"] == "XRAYIMAGING":
|
|
225
|
+
fnam = values["results"]["IMAGELINK"]
|
|
226
|
+
if fnam is not None and len(fnam)>0:
|
|
227
|
+
P = Path(fnam).expanduser().resolve()
|
|
228
|
+
if P.exists():
|
|
229
|
+
A = ITkDButils.Attachment(P.as_posix(), P.name, "X-ray image")
|
|
230
|
+
values["results"]["IMAGELINK"] = P.name
|
|
231
|
+
attachments.append(A)
|
|
232
|
+
|
|
233
|
+
rc = ITkDButils.upload_test(self.session, values, attachments=attachments)
|
|
234
|
+
if rc is not None:
|
|
235
|
+
dbGtkUtils.complain("Could not upload test", rc)
|
|
236
|
+
|
|
237
|
+
else:
|
|
238
|
+
self.write_message("Test uploaded. {} - {}\n".format(values["component"], values["testType"]))
|
|
239
|
+
|
|
216
240
|
def upload_single_test(self, *args):
|
|
217
241
|
"""Upload the current test."""
|
|
218
242
|
SN = self.SN.get_text()
|
|
@@ -225,16 +249,9 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
225
249
|
if dctD is None:
|
|
226
250
|
return
|
|
227
251
|
|
|
228
|
-
values = dctD.values
|
|
252
|
+
values = copy.deepcopy(dctD.values)
|
|
229
253
|
values["component"] = SN
|
|
230
|
-
|
|
231
|
-
rc = ITkDButils.upload_test(self.session, values)
|
|
232
|
-
if rc is not None:
|
|
233
|
-
dbGtkUtils.complain("Could not upload test", rc)
|
|
234
|
-
|
|
235
|
-
else:
|
|
236
|
-
dbGtkUtils.ask_for_confirmation("Test uploaded.",
|
|
237
|
-
"{} - {}".format(values["component"], values["testType"]))
|
|
254
|
+
self.upload_this_test(values)
|
|
238
255
|
|
|
239
256
|
def upload_tests(self, *args):
|
|
240
257
|
"""Upload the current test."""
|
|
@@ -251,14 +268,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
|
|
|
251
268
|
|
|
252
269
|
values = dctD.values
|
|
253
270
|
values["component"] = SN
|
|
254
|
-
|
|
255
|
-
rc = ITkDButils.upload_test(self.session, values)
|
|
256
|
-
if rc is not None:
|
|
257
|
-
dbGtkUtils.complain("Could not upload test", rc)
|
|
258
|
-
|
|
259
|
-
else:
|
|
260
|
-
self.write_message("Test uploaded. {} - {}\n".format(values["component"], values["testType"]))
|
|
261
|
-
|
|
271
|
+
self.upload_this_test(values)
|
|
262
272
|
|
|
263
273
|
def main():
|
|
264
274
|
"""Main entry."""
|
|
@@ -469,7 +469,7 @@ class UploadMultipleTests(dbGtkUtils.ITkDBWindow):
|
|
|
469
469
|
if path.exists():
|
|
470
470
|
path = path.expanduser().resolve()
|
|
471
471
|
else:
|
|
472
|
-
path = folder / path
|
|
472
|
+
path = folder / path.name
|
|
473
473
|
|
|
474
474
|
if path.exists():
|
|
475
475
|
attachments.append(ITkDButils.Attachment(path, att["title"], att["description"]))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
""" itkdb-gtk python module
|
|
2
2
|
"""
|
|
3
|
-
__version__ = "0.10.
|
|
3
|
+
__version__ = "0.10.9.dev1"
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def dash_board():
|
|
@@ -57,3 +57,8 @@ def uploadPetalInformation():
|
|
|
57
57
|
"""Read files from AVS nd create Petal core in PDB."""
|
|
58
58
|
from .UploadPetalInformation import main
|
|
59
59
|
main()
|
|
60
|
+
|
|
61
|
+
def panelVisualInspection():
|
|
62
|
+
"""Visual inspection of PWB or HYB panels."""
|
|
63
|
+
from .panelVisualInspection import main
|
|
64
|
+
main()
|
|
@@ -21,6 +21,7 @@ from itkdb_gtk import UploadMultipleTests
|
|
|
21
21
|
from itkdb_gtk import GlueWeight
|
|
22
22
|
from itkdb_gtk import UploadModuleIV
|
|
23
23
|
from itkdb_gtk import WireBondGui
|
|
24
|
+
from itkdb_gtk import PanelVisualInspection
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
HAS_PETALQC=False
|
|
@@ -51,8 +52,10 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
51
52
|
GLUE_WEIGHT = 6
|
|
52
53
|
MOD_IV = 7
|
|
53
54
|
WIRE_BOND = 8
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
PANEL_VI = 9
|
|
56
|
+
PETAL_CORE_METRO = 10
|
|
57
|
+
PETAL_CORE_THERMAL = 11
|
|
58
|
+
|
|
56
59
|
|
|
57
60
|
def __init__(self, session):
|
|
58
61
|
"""Initialization."""
|
|
@@ -102,6 +105,12 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
102
105
|
btnWireBond = Gtk.Button(label="Wire Bond")
|
|
103
106
|
btnWireBond.connect("clicked", self.wire_bond)
|
|
104
107
|
grid.attach(btnWireBond, 1, irow, 1, 1)
|
|
108
|
+
|
|
109
|
+
irow += 1
|
|
110
|
+
btnModIV = Gtk.Button(label="Panel Visual Insp.")
|
|
111
|
+
btnModIV.connect("clicked", self.panel_VI)
|
|
112
|
+
grid.attach(btnModIV, 0, irow, 1, 1)
|
|
113
|
+
|
|
105
114
|
|
|
106
115
|
if HAS_PETALQC:
|
|
107
116
|
irow +=1
|
|
@@ -225,6 +234,19 @@ class DashWindow(dbGtkUtils.ITkDBWindow):
|
|
|
225
234
|
W.connect("destroy", self.app_closed, bitn)
|
|
226
235
|
W.show_all()
|
|
227
236
|
|
|
237
|
+
def panel_VI(self, *args):
|
|
238
|
+
"""Panel VI tests."""
|
|
239
|
+
bitn = DashWindow.PANEL_VI
|
|
240
|
+
bt = 1 << bitn
|
|
241
|
+
if self.mask & bt:
|
|
242
|
+
return
|
|
243
|
+
|
|
244
|
+
self.mask |= bt
|
|
245
|
+
W = PanelVisualInspection.PanelVisualInspection(session=self.session, title="Panel Visual Inspection", help=HELP_LINK)
|
|
246
|
+
W.connect("destroy", self.app_closed, bitn)
|
|
247
|
+
W.show_all()
|
|
248
|
+
|
|
249
|
+
|
|
228
250
|
def petal_metrology(self, *args):
|
|
229
251
|
"""Do petal metrology"""
|
|
230
252
|
if not HAS_PETALQC:
|
|
@@ -69,6 +69,10 @@ def parse_date_as_string(txt):
|
|
|
69
69
|
def is_a_date(txt):
|
|
70
70
|
"""check tha the input string is a date."""
|
|
71
71
|
try:
|
|
72
|
+
tl = txt.lower()
|
|
73
|
+
if len(txt)<5 and (tl!="now" and tl!="today"):
|
|
74
|
+
return False
|
|
75
|
+
|
|
72
76
|
dateutil.parser.parse(txt, fuzzy=False)
|
|
73
77
|
return True
|
|
74
78
|
|
|
@@ -94,7 +98,7 @@ def set_entry_style(container):
|
|
|
94
98
|
css = "{} {{ min-height: {}px; }}".format(container.get_name(), font_size)
|
|
95
99
|
provider.load_from_data(css.encode())
|
|
96
100
|
style_context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_SETTINGS)
|
|
97
|
-
return container
|
|
101
|
+
return container
|
|
98
102
|
|
|
99
103
|
def set_button_color(btn, bg_color, fg_color="white"):
|
|
100
104
|
"""Set button color"""
|
|
@@ -103,7 +107,7 @@ def set_button_color(btn, bg_color, fg_color="white"):
|
|
|
103
107
|
provider.load_from_data(css.encode())
|
|
104
108
|
style_context = btn.get_style_context()
|
|
105
109
|
style_context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_USER)
|
|
106
|
-
|
|
110
|
+
|
|
107
111
|
def set_combo_iter(combo, txt, col=0):
|
|
108
112
|
"""Set scombo active iter to that containing txt in column col."""
|
|
109
113
|
model = combo.get_model()
|
|
@@ -247,7 +251,7 @@ class TextEntry(GObject.GObject):
|
|
|
247
251
|
self.widget = new_small_text_entry()
|
|
248
252
|
else:
|
|
249
253
|
self.widget = Gtk.Entry()
|
|
250
|
-
|
|
254
|
+
|
|
251
255
|
self.widget.connect("focus-in-event", self.on_enter)
|
|
252
256
|
self.widget.connect("focus-out-event", self.on_leave)
|
|
253
257
|
|
|
@@ -480,7 +484,7 @@ class MessagePanel(object):
|
|
|
480
484
|
|
|
481
485
|
self.textbuffer.insert(end, msg)
|
|
482
486
|
GLib.idle_add(self.scroll_to_end)
|
|
483
|
-
|
|
487
|
+
|
|
484
488
|
def write(self, txt):
|
|
485
489
|
"""A write method."""
|
|
486
490
|
self.write_message(txt, write_date=False)
|
|
@@ -533,7 +537,7 @@ class ITkDBWindow(Gtk.Window):
|
|
|
533
537
|
button.set_tooltip_text(show_search)
|
|
534
538
|
button.connect("clicked", self.query_db)
|
|
535
539
|
self.hb.pack_end(button)
|
|
536
|
-
|
|
540
|
+
|
|
537
541
|
if self.help:
|
|
538
542
|
button = Gtk.Button()
|
|
539
543
|
icon = Gio.ThemedIcon(name="help-browser-symbolic")
|
|
@@ -541,7 +545,7 @@ class ITkDBWindow(Gtk.Window):
|
|
|
541
545
|
button.add(image)
|
|
542
546
|
button.connect("clicked", self.show_help)
|
|
543
547
|
self.hb.pack_end(button)
|
|
544
|
-
|
|
548
|
+
|
|
545
549
|
|
|
546
550
|
# Create main content box
|
|
547
551
|
self.mainBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
@@ -570,7 +574,7 @@ class ITkDBWindow(Gtk.Window):
|
|
|
570
574
|
def show_help(self, *args):
|
|
571
575
|
"""Show help"""
|
|
572
576
|
webbrowser.open(self.help)
|
|
573
|
-
|
|
577
|
+
|
|
574
578
|
def query_db(self, *args):
|
|
575
579
|
"""Search button clicked."""
|
|
576
580
|
pass
|
|
@@ -580,7 +584,7 @@ class ITkDBWindow(Gtk.Window):
|
|
|
580
584
|
if msg == "<OK>":
|
|
581
585
|
if hasattr(self.session, "user_gui"):
|
|
582
586
|
self.session = self.session.user_gui.get_client()
|
|
583
|
-
|
|
587
|
+
|
|
584
588
|
if self.userLabel.get_child():
|
|
585
589
|
self.userLabel.get_child().set_text(self.session.user.name)
|
|
586
590
|
|
|
@@ -725,7 +729,7 @@ class DictDialog(Gtk.Grid):
|
|
|
725
729
|
else:
|
|
726
730
|
if itm[last_key] is None:
|
|
727
731
|
itm[last_key] = txt
|
|
728
|
-
else:
|
|
732
|
+
else:
|
|
729
733
|
tp = type(itm[last_key])
|
|
730
734
|
itm[last_key] = tp(txt)
|
|
731
735
|
|
|
@@ -765,6 +769,7 @@ class DictDialog(Gtk.Grid):
|
|
|
765
769
|
css = "entry {{ min-height: {}px; }}".format(font_size)
|
|
766
770
|
provider.load_from_data(css.encode())
|
|
767
771
|
style_context.add_provider(provider, Gtk.STYLE_PROVIDER_PRIORITY_SETTINGS)
|
|
772
|
+
container.connect("populate-popup", self.add_insert_path)
|
|
768
773
|
|
|
769
774
|
if name:
|
|
770
775
|
container.set_name(name)
|
|
@@ -775,6 +780,28 @@ class DictDialog(Gtk.Grid):
|
|
|
775
780
|
|
|
776
781
|
return container
|
|
777
782
|
|
|
783
|
+
def add_insert_path(self, entry, menu, *args):
|
|
784
|
+
"""Adds a new item in the pop-up menu."""
|
|
785
|
+
item = Gtk.MenuItem(label="Get file path")
|
|
786
|
+
item.connect("activate", self.on_set_path, entry)
|
|
787
|
+
menu.append(item)
|
|
788
|
+
menu.show_all()
|
|
789
|
+
|
|
790
|
+
def on_set_path(self, menu_item, entry):
|
|
791
|
+
"""Sets the path to the entry."""
|
|
792
|
+
fdlg = Gtk.FileChooserNative(action=Gtk.FileChooserAction.OPEN, accept_label="Select")
|
|
793
|
+
response = fdlg.run()
|
|
794
|
+
if response == Gtk.ResponseType.ACCEPT:
|
|
795
|
+
ifiles = [ipath for ipath in fdlg.get_filenames()]
|
|
796
|
+
if len(ifiles)<1:
|
|
797
|
+
return
|
|
798
|
+
if len(ifiles) > 1:
|
|
799
|
+
complain("More than one file selected","Choosing first.")
|
|
800
|
+
|
|
801
|
+
fnam = ifiles[0]
|
|
802
|
+
entry.set_text(fnam)
|
|
803
|
+
self.on_leave(entry, None, None, entry.get_name())
|
|
804
|
+
|
|
778
805
|
def set_value(self, key, value):
|
|
779
806
|
"""Set value of a container and key."""
|
|
780
807
|
try:
|
|
@@ -815,7 +842,7 @@ class DictDialog(Gtk.Grid):
|
|
|
815
842
|
self.show_values()
|
|
816
843
|
self.show_all()
|
|
817
844
|
self.queue_draw()
|
|
818
|
-
|
|
845
|
+
|
|
819
846
|
@staticmethod
|
|
820
847
|
def create_json_data_editor(data):
|
|
821
848
|
"""Create a dialog to show the JSon file."""
|
|
@@ -835,7 +862,7 @@ class DictDialog(Gtk.Grid):
|
|
|
835
862
|
rc = dlg.run()
|
|
836
863
|
dlg.hide()
|
|
837
864
|
dlg.destroy()
|
|
838
|
-
|
|
865
|
+
|
|
839
866
|
return value.values, rc
|
|
840
867
|
|
|
841
868
|
|
|
@@ -844,7 +871,7 @@ def create_scrolled_dictdialog(the_dict, hidden=("component", "testType")):
|
|
|
844
871
|
|
|
845
872
|
Args:
|
|
846
873
|
the_dict: the input dictionary with values.
|
|
847
|
-
|
|
874
|
+
|
|
848
875
|
Returns:
|
|
849
876
|
scrolled: the scrolled window
|
|
850
877
|
gM: the DictDialog
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: itkdb_gtk
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.9.dev1
|
|
4
4
|
Summary: A collection of Gtk based GUI to access ITkDB.
|
|
5
5
|
Author-email: Carlos Lacasta <carlos.lacasta@cern.ch>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.cern.ch/atlas-itk/sw/db/itk-pdb-gtk-gui-utils
|
|
@@ -3,6 +3,7 @@ createShipments = itkdb_gtk:createShipments
|
|
|
3
3
|
getShipments = itkdb_gtk:getShipments
|
|
4
4
|
glueWeight = itkdb_gtk:glueWeight
|
|
5
5
|
itkdb_dashBoard = itkdb_gtk:dash_board
|
|
6
|
+
panelVisualInspection = itkdb_gtk:panelVisualInspection
|
|
6
7
|
petalReceptionTests = itkdb_gtk:petalReceptionTests
|
|
7
8
|
uploadModuleIV = itkdb_gtk:uploadModuleIV
|
|
8
9
|
uploadMultipleTests = itkdb_gtk:uploadMultipleTests
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "itkdb_gtk"
|
|
7
|
-
version = "0.10.
|
|
7
|
+
version = "0.10.9.dev1"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Carlos Lacasta", email="carlos.lacasta@cern.ch" },
|
|
10
10
|
]
|
|
@@ -37,6 +37,7 @@ uploadMultipleTests = "itkdb_gtk:uploadMultipleTests"
|
|
|
37
37
|
uploadModuleIV = "itkdb_gtk:uploadModuleIV"
|
|
38
38
|
wirebondTest = "itkdb_gtk:wirebondTest"
|
|
39
39
|
uploadPetalInformation = "itkdb_gtk:uploadPetalInformation"
|
|
40
|
+
panelVisualInspection = "itkdb_gtk:panelVisualInspection"
|
|
40
41
|
|
|
41
42
|
[tool.setuptools]
|
|
42
43
|
include-package-data = true
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bine/env python3
|
|
2
|
+
"""test big attachments."""
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import sys
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import itkdb
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import itkdb_gtk
|
|
11
|
+
|
|
12
|
+
except ImportError:
|
|
13
|
+
cwd = Path(__file__).parent.parent
|
|
14
|
+
sys.path.append(cwd.as_posix())
|
|
15
|
+
|
|
16
|
+
from itkdb_gtk import ITkDBlogin, ITkDButils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# DB login
|
|
20
|
+
dlg = ITkDBlogin.ITkDBlogin()
|
|
21
|
+
client = dlg.get_client(use_eos=True)
|
|
22
|
+
if client is None:
|
|
23
|
+
print("Could not connect to DB with provided credentials.")
|
|
24
|
+
dlg.die()
|
|
25
|
+
sys.exit()
|
|
26
|
+
|
|
27
|
+
client.user_gui = dlg
|
|
28
|
+
|
|
29
|
+
ifile = Path("/Users/lacasta/Nextcloud/ITk/5-Petal_cores/PPC.007/Rx_PPC.007.png")
|
|
30
|
+
core = ITkDButils.get_DB_component(client, "PPC.007")
|
|
31
|
+
data = { "filterMap": { "serialNumber": core["serialNumber"], "testType":["XRAYIMAGING"]},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test_list = client.get("listTestRunsByComponent", json=data)
|
|
35
|
+
ntest = 0
|
|
36
|
+
for tst in test_list:
|
|
37
|
+
if tst['state'] == 'ready':
|
|
38
|
+
ntest += 1
|
|
39
|
+
|
|
40
|
+
if ntest == 0:
|
|
41
|
+
defaults = {
|
|
42
|
+
"institution": "IFIC",
|
|
43
|
+
"runNumber": "1",
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tmp = ITkDButils.get_test_skeleton(client, "CORE_PETAL", "XRAYIMAGING", defaults)
|
|
47
|
+
tmp["component"] = core["serialNumber"]
|
|
48
|
+
tmp["properties"]["OPERATOR"] = "Nicolas Cespedosa"
|
|
49
|
+
tmp["properties"]["MACHINEID"] ="X-ray"
|
|
50
|
+
print(tmp)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#client._use_eos = True
|
|
56
|
+
A = ITkDButils.Attachment(ifile.as_posix(),
|
|
57
|
+
"{} X-ray".format(core["alternativeIdentifier"]),
|
|
58
|
+
"{} X-ray image".format(core["alternativeIdentifier"])
|
|
59
|
+
)
|
|
60
|
+
rc = ITkDButils.upload_test(client, data=tmp, attachments=[A])
|
|
61
|
+
|
|
62
|
+
if rc:
|
|
63
|
+
ipos = rc.find("The following details may help:")
|
|
64
|
+
print(rc[ipos:])
|
|
65
|
+
|
|
66
|
+
else:
|
|
67
|
+
print("upload successful")
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
dlg.die()
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""PB/Hybrid panel Visual inspection GUI.."""
|
|
3
|
-
import json
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
try:
|
|
7
|
-
import itkdb_gtk
|
|
8
|
-
|
|
9
|
-
except ImportError:
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
cwd = Path(__file__).parent.parent
|
|
12
|
-
sys.path.append(cwd.as_posix())
|
|
13
|
-
|
|
14
|
-
from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
|
|
15
|
-
|
|
16
|
-
import gi
|
|
17
|
-
gi.require_version("Gtk", "3.0")
|
|
18
|
-
from gi.repository import Gtk, Gdk, Gio
|
|
19
|
-
|
|
20
|
-
HELP_LINK="https://itkdb-gtk.docs.cern.ch"
|
|
21
|
-
|
|
22
|
-
class PanelVisualInspection(dbGtkUtils.ITkDBWindow):
|
|
23
|
-
"""PB/Hybryd panel visual inspection GUI."""
|
|
24
|
-
SN, PASSED, ALL = range(3)
|
|
25
|
-
|
|
26
|
-
def __init__(self, session, help=HELP_LINK):
|
|
27
|
-
super().__init__(title="ITkDB Dashboard",
|
|
28
|
-
session=session,
|
|
29
|
-
show_search="Find object with given SN.",
|
|
30
|
-
help=help)
|
|
31
|
-
|
|
32
|
-
# action button in header
|
|
33
|
-
button = Gtk.Button()
|
|
34
|
-
icon = Gio.ThemedIcon(name="document-send-symbolic")
|
|
35
|
-
image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON)
|
|
36
|
-
button.add(image)
|
|
37
|
-
button.set_tooltip_text("Click to upload ALL tests.")
|
|
38
|
-
button.connect("clicked", self.upload_tests)
|
|
39
|
-
self.hb.pack_end(button)
|
|
40
|
-
|
|
41
|
-
grid = Gtk.Grid(column_spacing=5, row_spacing=1)
|
|
42
|
-
self.mainBox.pack_start(grid, False, False, 5)
|
|
43
|
-
|
|
44
|
-
lbl = Gtk.Label(label="Serial Number")
|
|
45
|
-
lbl.set_xalign(0)
|
|
46
|
-
grid.attach(lbl, 0, 0, 1, 1)
|
|
47
|
-
|
|
48
|
-
self.SN = dbGtkUtils.TextEntry()
|
|
49
|
-
self.SN.connect("text_changed", self.SN_ready)
|
|
50
|
-
self.SN.widget.set_tooltip_text("Enter SN of PWD or Hybrid panel.")
|
|
51
|
-
grid.attach(self.SN.widget, 1, 0, 1, 1)
|
|
52
|
-
|
|
53
|
-
self.panel_type = Gtk.Label(label="")
|
|
54
|
-
grid.attach(self.panel_type, 2, 0, 1, 1)
|
|
55
|
-
|
|
56
|
-
# Paned object
|
|
57
|
-
paned = Gtk.Paned(orientation=Gtk.Orientation.VERTICAL)
|
|
58
|
-
paned.set_size_request(-1, 200)
|
|
59
|
-
self.mainBox.pack_start(paned, True, True, 5)
|
|
60
|
-
|
|
61
|
-
# the list of attachments
|
|
62
|
-
tree_view = self.create_tree_view()
|
|
63
|
-
paned.add1(tree_view)
|
|
64
|
-
|
|
65
|
-
# The text view
|
|
66
|
-
paned.add2(self.message_panel.frame)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
self.show_all()
|
|
70
|
-
|
|
71
|
-
dbGtkUtils.setup_scanner(self.get_qrcode)
|
|
72
|
-
|
|
73
|
-
def create_tree_view(self, size=150):
|
|
74
|
-
"""Create the TreeView with the children."""
|
|
75
|
-
model = Gtk.ListStore(str, bool)
|
|
76
|
-
self.tree = Gtk.TreeView(model=model)
|
|
77
|
-
|
|
78
|
-
scrolled = Gtk.ScrolledWindow()
|
|
79
|
-
scrolled.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
|
80
|
-
scrolled.add(self.tree)
|
|
81
|
-
scrolled.set_size_request(-1, size)
|
|
82
|
-
|
|
83
|
-
renderer = Gtk.CellRendererText()
|
|
84
|
-
column = Gtk.TreeViewColumn("SN", renderer, text=PanelVisualInspection.SN)
|
|
85
|
-
self.tree.append_column(column)
|
|
86
|
-
|
|
87
|
-
renderer = Gtk.CellRendererToggle()
|
|
88
|
-
renderer.set_property("activatable", True)
|
|
89
|
-
renderer.set_property("radio", True)
|
|
90
|
-
renderer.set_padding(5, 0)
|
|
91
|
-
|
|
92
|
-
x, y = renderer.get_alignment()
|
|
93
|
-
renderer.set_alignment(0, y)
|
|
94
|
-
# renderer.set_property("inconsistent", True)
|
|
95
|
-
renderer.connect("toggled", self.btn_toggled)
|
|
96
|
-
|
|
97
|
-
column = Gtk.TreeViewColumn("Passed", renderer, active=PanelVisualInspection.PASSED)
|
|
98
|
-
self.tree.append_column(column)
|
|
99
|
-
|
|
100
|
-
return scrolled
|
|
101
|
-
|
|
102
|
-
def btn_toggled(self, renderer, path, *args):
|
|
103
|
-
"""Toggled."""
|
|
104
|
-
model = self.tree.get_model()
|
|
105
|
-
val = not model[path][PanelVisualInspection.PASSED]
|
|
106
|
-
model[path][PanelVisualInspection.PASSED] = val
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def button_pressed(self, tree, event):
|
|
110
|
-
"""Button pressed on tree view."""
|
|
111
|
-
# double click shows attachments
|
|
112
|
-
if event.button == 1 and event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS:
|
|
113
|
-
select = self.tree.get_selection()
|
|
114
|
-
model, iter = select.get_selected()
|
|
115
|
-
if not iter:
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
self.on_show_json(None, (model, iter, model[iter]))
|
|
119
|
-
# self.on_show_attachments(None, (model, iter, model[iter]))
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
if event.button != 3:
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
# Create popup menu
|
|
126
|
-
select = self.tree.get_selection()
|
|
127
|
-
model, iter = select.get_selected()
|
|
128
|
-
values = None
|
|
129
|
-
if iter:
|
|
130
|
-
values = model[iter]
|
|
131
|
-
|
|
132
|
-
if not iter:
|
|
133
|
-
P = tree.get_path_at_pos(event.x, event.y)
|
|
134
|
-
if P:
|
|
135
|
-
print(P[0].to_string())
|
|
136
|
-
iter = model.get_iter(P[0])
|
|
137
|
-
values = model[iter]
|
|
138
|
-
|
|
139
|
-
if not values:
|
|
140
|
-
return
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
def SN_ready(self, *args):
|
|
144
|
-
"""SN is ready in the TextEnttry."""
|
|
145
|
-
SN = self.SN.get_text()
|
|
146
|
-
if not SN.startswith("20U") or len(SN)!=14:
|
|
147
|
-
dbGtkUtils.complain("Invalid Serial Number",
|
|
148
|
-
"{}: wrong SN".format(SN))
|
|
149
|
-
return
|
|
150
|
-
|
|
151
|
-
if "USED" in SN:
|
|
152
|
-
# Powerboard Carrier
|
|
153
|
-
if not SN[6].isdigit():
|
|
154
|
-
dbGtkUtils.complain("Not a Powerboard Carrier",
|
|
155
|
-
"{}: wrong SN for a powerboard carrier".format(SN))
|
|
156
|
-
self.SN.widget.set_text("")
|
|
157
|
-
return
|
|
158
|
-
|
|
159
|
-
self.panel_type.set_text("PWB carrier")
|
|
160
|
-
|
|
161
|
-
elif "USET" in SN:
|
|
162
|
-
# Hybrid test panel
|
|
163
|
-
if not SN[6].isdigit or int(SN[6])>5:
|
|
164
|
-
dbGtkUtils.complain("Not a Hybrid Test Panel",
|
|
165
|
-
"{}: wrong SN for a hybrid test panel".format(SN))
|
|
166
|
-
self.SN.widget.set_text("")
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
else:
|
|
170
|
-
dbGtkUtils.complain("Invalid SN.",
|
|
171
|
-
"{}\nNot a PWB carrier not HYB test panel.".format(SN))
|
|
172
|
-
self.SN.widget.set_text("")
|
|
173
|
-
return
|
|
174
|
-
|
|
175
|
-
# GEt children.
|
|
176
|
-
panel = ITkDButils.get_DB_component(self.session, SN)
|
|
177
|
-
if panel is None:
|
|
178
|
-
self.write_message(ITkDButils.get_db_response())
|
|
179
|
-
return
|
|
180
|
-
|
|
181
|
-
children = []
|
|
182
|
-
for child in panel["children"]:
|
|
183
|
-
if child["component"] is not None:
|
|
184
|
-
if child["componentType"]["name"] == "Powerboard":
|
|
185
|
-
children.append(child["component"]["serialNumber"])
|
|
186
|
-
|
|
187
|
-
model = Gtk.ListStore(str, bool)
|
|
188
|
-
for child in children:
|
|
189
|
-
model.append([SN, True])
|
|
190
|
-
|
|
191
|
-
self.tree.set_model(model)
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def upload_tests(self, *args):
|
|
195
|
-
"""Upload the current test."""
|
|
196
|
-
SN = self.SN.get_text()
|
|
197
|
-
|
|
198
|
-
def get_qrcode(self, fd, state, reader):
|
|
199
|
-
"""Read SN from scanner."""
|
|
200
|
-
txt = dbGtkUtils.scanner_get_line(reader)
|
|
201
|
-
self.write_message("SN: {}\n".format(txt))
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
def main():
|
|
205
|
-
"""Main entry."""
|
|
206
|
-
# DB login
|
|
207
|
-
dlg = ITkDBlogin.ITkDBlogin()
|
|
208
|
-
client = dlg.get_client()
|
|
209
|
-
if client is None:
|
|
210
|
-
print("Could not connect to DB with provided credentials.")
|
|
211
|
-
dlg.die()
|
|
212
|
-
sys.exit()
|
|
213
|
-
|
|
214
|
-
client.user_gui = dlg
|
|
215
|
-
|
|
216
|
-
gTest = PanelVisualInspection(client)
|
|
217
|
-
|
|
218
|
-
gTest.present()
|
|
219
|
-
gTest.connect("destroy", Gtk.main_quit)
|
|
220
|
-
try:
|
|
221
|
-
Gtk.main()
|
|
222
|
-
|
|
223
|
-
except KeyboardInterrupt:
|
|
224
|
-
print("Arrrgggg!!!")
|
|
225
|
-
|
|
226
|
-
dlg.die()
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if __name__ == "__main__":
|
|
230
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|