itkdb-gtk 0.10.9.dev4__tar.gz → 0.10.10.dev2__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.

Files changed (39) hide show
  1. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/PKG-INFO +1 -1
  2. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/CreateShipments.py +5 -2
  3. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/GetShipments.py +27 -44
  4. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ITkDBlogin.py +6 -2
  5. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ITkDButils.py +19 -2
  6. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/PanelVisualInspection.py +2 -2
  7. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/PetalReceptionTests.py +11 -4
  8. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/UploadPetalInformation.py +41 -2
  9. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/UploadTest.py +1 -1
  10. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/WireBondGui.py +177 -12
  11. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/__init__.py +1 -1
  12. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/dbGtkUtils.py +60 -17
  13. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/readAVSdata.py +5 -5
  14. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/PKG-INFO +1 -1
  15. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/SOURCES.txt +1 -0
  16. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/pyproject.toml +1 -1
  17. itkdb_gtk-0.10.10.dev2/test/testBatch.py +87 -0
  18. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/README.md +0 -0
  19. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/GlueWeight.py +0 -0
  20. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ITkDB.desktop +0 -0
  21. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ITkDB.svg +0 -0
  22. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/SensorUtils.py +0 -0
  23. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ShowAttachments.py +0 -0
  24. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ShowComments.py +0 -0
  25. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/ShowDefects.py +0 -0
  26. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/UploadModuleIV.py +0 -0
  27. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/UploadMultipleTests.py +0 -0
  28. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/dashBoard.py +0 -0
  29. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/readGoogleSheet.py +0 -0
  30. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk/untrash_component.py +0 -0
  31. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/dependency_links.txt +0 -0
  32. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/entry_points.txt +0 -0
  33. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/requires.txt +0 -0
  34. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/itkdb_gtk.egg-info/top_level.txt +0 -0
  35. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/setup.cfg +0 -0
  36. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/test/testAnimated.py +0 -0
  37. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/test/testComponent.py +0 -0
  38. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/test/test_attachment.py +0 -0
  39. {itkdb_gtk-0.10.9.dev4 → itkdb_gtk-0.10.10.dev2}/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.9.dev4
3
+ Version: 0.10.10.dev2
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
@@ -19,7 +19,7 @@ from itkdb_gtk import dbGtkUtils, ITkDBlogin, ITkDButils
19
19
 
20
20
  import gi
21
21
  gi.require_version("Gtk", "3.0")
22
- from gi.repository import Gtk, Gio, GLib
22
+ from gi.repository import Gtk, Gio
23
23
 
24
24
  # Check if Gtk can be open
25
25
  gtk_runs, gtk_args = Gtk.init_check()
@@ -181,6 +181,9 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
181
181
  # For the later we get the SN in the argument list.
182
182
  if isinstance(args[0], Gtk.Button):
183
183
  txt = dbGtkUtils.get_a_value("Enter item SN", is_tv=True)
184
+ if txt is None:
185
+ return
186
+
184
187
  tmp = re.split(';|,| |\n|\t', txt)
185
188
  SNlist = [s.strip() for s in tmp if len(s.strip())>0]
186
189
  else:
@@ -346,7 +349,7 @@ class CreateShipments(dbGtkUtils.ITkDBWindow):
346
349
  self.tree.set_model(model)
347
350
  self.comments.set_text("")
348
351
  self.name.set_text("")
349
- self.attachments = None
352
+ self.attachment = None
350
353
 
351
354
  else:
352
355
  self.write_message("Empty list of items when creating shipment.")
@@ -44,7 +44,7 @@ def find_vtrx(client, SN):
44
44
  class ReceiveShipments(dbGtkUtils.ITkDBWindow):
45
45
  """Find shipments related to given recipient."""
46
46
 
47
- def __init__(self, session, recipient="IFIC", help_link=None):
47
+ def __init__(self, session, recipient=None, help_link=None):
48
48
  """Initialization.
49
49
 
50
50
  Args:
@@ -52,7 +52,6 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
52
52
  recipient: default recipient
53
53
 
54
54
  """
55
- self.recipient = recipient
56
55
  self.state = "inTransit"
57
56
  self.institute = None
58
57
  self.model = None
@@ -62,11 +61,15 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
62
61
 
63
62
  global gtk_runs
64
63
  if gtk_runs:
65
- super().__init__(session=session, title="Upload AVS Data",
64
+ super().__init__(session=session, title="Receive Shipments",
66
65
  show_search="Click to search shipments",
67
66
  gtk_runs=gtk_runs, help_link=help_link)
68
67
 
68
+ self.recipient = self.pdb_user["institutions"][0]["code"]
69
69
  self.init_window()
70
+ else:
71
+ pdb_user = ITkDButils.get_db_user(session)
72
+ self.recipient = pdb_user["institutions"][0]["code"]
70
73
 
71
74
  def init_window(self):
72
75
  """Initialize window."""
@@ -93,7 +96,7 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
93
96
  self.mainBox.pack_start(grid, False, True, 0)
94
97
 
95
98
  # The shipment receiver
96
- receiver = self.create_institute_combo()
99
+ receiver = self.create_institute_combo(only_user=True)
97
100
  receiver.connect("changed", self.on_receiver)
98
101
  receiver.set_tooltip_text("Select the Institute receiving the items.")
99
102
  dbGtkUtils.set_combo_iter(receiver, self.recipient)
@@ -198,21 +201,6 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
198
201
 
199
202
  return True
200
203
 
201
- def get_institute_list(self):
202
- """Get the institute list."""
203
- sites = self.session.get("listInstitutions", json={})
204
- liststore = Gtk.ListStore(str, str)
205
- for site in sites:
206
- self.code2inst[site['code']] = site['name']
207
- self.inst2code[site['name']] = site['code']
208
- liststore.append([site["code"], site["code"]])
209
- liststore.append([site["name"], site["code"]])
210
-
211
- completion = Gtk.EntryCompletion()
212
- completion.set_model(liststore)
213
- completion.set_text_column(0)
214
- return completion
215
-
216
204
  def on_cell_toggled(self, widget, path):
217
205
  """A cell has been toggled."""
218
206
  model = self.tree.get_model()
@@ -249,30 +237,12 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
249
237
 
250
238
  self.state = name
251
239
 
252
- def get_institute_from_combo(self, combo):
253
- """Get Institute from combo."""
254
- tree_iter = combo.get_active_iter()
255
- if tree_iter is not None:
256
- model = combo.get_model()
257
- name = model[tree_iter][1]
258
-
259
- else:
260
- name = combo.get_child().get_text()
261
- if name in self.inst2code:
262
- name = self.inst2code[name]
263
-
264
- elif name not in self.code2inst:
265
- name = None
266
-
267
- return name
268
-
269
240
  def on_receiver(self, combo):
270
241
  """Sets the recipient."""
271
242
  name = self.get_institute_from_combo(combo)
272
243
  if name:
273
244
  self.recipient = name
274
- hb = self.get_titlebar()
275
- hb.props.title = "{} shipments".format(self.recipient)
245
+ self.set_window_title("{} shipments".format(self.recipient))
276
246
 
277
247
  def on_institute(self, combo):
278
248
  """New institute chosen."""
@@ -286,12 +256,14 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
286
256
 
287
257
  def query_db(self, *args):
288
258
  """Query for shipments in DB."""
289
- if self.institute is None or self.state == "":
259
+ if self.state == "":
290
260
  return
291
261
 
292
262
  payload = {
293
- "code": self.recipient,
294
- "status": self.state
263
+ "filterMap": {
264
+ "code": self.recipient,
265
+ "status": self.state
266
+ }
295
267
  }
296
268
  shpmts = self.session.get("listShipmentsByInstitution", json=payload)
297
269
 
@@ -300,7 +272,11 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
300
272
  # the tree view.
301
273
  cmb_store = Gtk.ListStore(str, str)
302
274
  for s in shpmts:
303
- if s["recipient"]["code"] == self.recipient and s['sender']['code'] == self.institute:
275
+ valid_sender = True
276
+ if self.institute is not None:
277
+ valid_sender = s['sender']['code'] == self.institute
278
+
279
+ if s["recipient"]["code"] == self.recipient and valid_sender:
304
280
  store = self.get_tree_view_model()
305
281
  cmb_store.append([s['name'], s['id']])
306
282
  items = self.session.get("listShipmentItems", json={"shipment": s["id"]})
@@ -318,8 +294,15 @@ class ReceiveShipments(dbGtkUtils.ITkDBWindow):
318
294
  self.write_message("Could not find any shipment in DB.\n")
319
295
 
320
296
  self.cmb_shipment.set_model(cmb_store)
321
- self.cmb_shipment.set_entry_text_column(0)
322
- self.cmb_shipment.set_active(0)
297
+ if len(cmb_store)>0:
298
+ self.cmb_shipment.set_entry_text_column(0)
299
+ self.cmb_shipment.set_active(0)
300
+ else:
301
+ self.cmb_shipment.set_active(-1)
302
+ self.cmb_shipment.get_child().set_text("")
303
+
304
+
305
+ self.tree.set_model(Gtk.ListStore(str, str, str, bool))
323
306
 
324
307
  def receive_items(self, *args):
325
308
  """Receive shipment items."""
@@ -239,10 +239,10 @@ class ITkDBlogin(Gtk.Dialog):
239
239
  self.ac1.set_visibility(False)
240
240
  self.ac2.set_visibility(False)
241
241
 
242
- grid.attach(Gtk.Label(label="Acces Code 1"), 0, irow, 1, 1)
242
+ grid.attach(Gtk.Label(label="Access Code 1"), 0, irow, 1, 1)
243
243
  grid.attach(self.ac1, 1, irow, 1, 1)
244
244
  irow = irow + 1
245
- grid.attach(Gtk.Label(label="Acces Code 1"), 0, irow, 1, 1)
245
+ grid.attach(Gtk.Label(label="Access Code 2"), 0, irow, 1, 1)
246
246
  grid.attach(self.ac2, 1, irow, 1, 1)
247
247
 
248
248
  btn = self.get_widget_for_response(Gtk.ResponseType.OK)
@@ -336,6 +336,10 @@ if __name__ == "__main__":
336
336
  # print(l)
337
337
 
338
338
  print("Hello {}".format(dlg.name))
339
+
340
+ rc = client.get("getUser", json={"userIdentity": dlg.user.identity})
341
+ print(rc)
342
+
339
343
  if gtk_runs:
340
344
  try:
341
345
  while True:
@@ -56,7 +56,6 @@ def get_db_response():
56
56
  It is stores in a global variable. Trust the function if call
57
57
  right after your interaction with the DB.
58
58
  """
59
- global db_response
60
59
  return db_response
61
60
 
62
61
 
@@ -84,7 +83,8 @@ def get_db_date(timestamp=None):
84
83
  try:
85
84
  this_date = dateutil.parser.parse(timestamp)
86
85
  out = date2string(this_date)
87
- except Exception:
86
+
87
+ except (OverflowError, dateutil.parser.ParserError):
88
88
  out = ""
89
89
 
90
90
  return out
@@ -666,3 +666,20 @@ def create_client():
666
666
  client.user.authenticate()
667
667
  print("Hello {} !".format(client.user.name))
668
668
  return client
669
+
670
+ def get_db_user(client):
671
+ """REturn PDB information of current user.
672
+
673
+ Args:
674
+ client (itkdb.Client): The DB client.
675
+
676
+ """
677
+ global db_response
678
+ if client is None:
679
+ return None
680
+
681
+ try:
682
+ db_response = client.get("getUser", json={"userIdentity": client.user.identity})
683
+ return db_response
684
+ except Exception:
685
+ return None
@@ -47,7 +47,7 @@ class PanelVisualInspection(dbGtkUtils.ITkDBWindow):
47
47
  show_search="Find object with given SN.",
48
48
  help_link=help_link)
49
49
 
50
- self.institute = "IFIC"
50
+ self.institute = self.pdb_user["institutions"][0]["code"]
51
51
  self.global_image = None
52
52
  self.global_link = None
53
53
 
@@ -64,7 +64,7 @@ class PanelVisualInspection(dbGtkUtils.ITkDBWindow):
64
64
  self.mainBox.pack_start(grid, False, False, 5)
65
65
 
66
66
  irow = 0
67
- receiver = self.create_institute_combo()
67
+ receiver = self.create_institute_combo(only_user=True)
68
68
  receiver.connect("changed", self.on_institute)
69
69
  receiver.set_tooltip_text("Select the Institute making the test.")
70
70
  dbGtkUtils.set_combo_iter(receiver, self.institute)
@@ -40,7 +40,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
40
40
 
41
41
  def __init__(self, session, help_link=None):
42
42
  """Initialization."""
43
- super().__init__(title="ITkDB Dashboard",
43
+ super().__init__(title="Petal Reception Tests",
44
44
  session=session,
45
45
  show_search="Find object with given SN.",
46
46
  help_link=help_link)
@@ -83,8 +83,8 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
83
83
  lbl.set_xalign(0)
84
84
  grid.attach(lbl, 0, 1, 1, 1)
85
85
 
86
- self.institute = "IFIC"
87
- inst = self.create_institute_combo()
86
+ self.institute = self.pdb_user["institutions"][0]["code"]
87
+ inst = self.create_institute_combo(only_user=True)
88
88
  inst.connect("changed", self.new_institute)
89
89
  inst.set_tooltip_text("Select the Institute.")
90
90
  grid.attach(inst, 1, 1, 1, 1)
@@ -114,6 +114,10 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
114
114
  # The text view
115
115
  self.mainBox.pack_end(self.message_panel.frame, True, True, 5)
116
116
 
117
+ # Set the default institute
118
+ dbGtkUtils.set_combo_iter(inst, self.institute)
119
+
120
+
117
121
  self.show_all()
118
122
 
119
123
  def on_SN_changed(self, entry, value):
@@ -139,7 +143,7 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
139
143
  page.dict_dialog.factory_reset()
140
144
 
141
145
 
142
- def create_test_box(self, label, test_name, institute="IFIC"):
146
+ def create_test_box(self, label, test_name, institute=None):
143
147
  """Create and add to notebook a test dialog.
144
148
 
145
149
  Args:
@@ -148,6 +152,9 @@ class PetalReceptionTests(dbGtkUtils.ITkDBWindow):
148
152
  institute: The institute.
149
153
 
150
154
  """
155
+ if institute is None:
156
+ institute = self.institute
157
+
151
158
  defaults = {
152
159
  "institution": institute,
153
160
  "runNumber": "1",
@@ -5,7 +5,6 @@ import sys
5
5
  from argparse import ArgumentParser
6
6
  from datetime import datetime, timezone
7
7
  from pathlib import Path
8
-
9
8
  import dateutil.parser
10
9
  import gi
11
10
 
@@ -119,6 +118,8 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
119
118
 
120
119
  self.btn_state = Gtk.Button(label="Undef")
121
120
  self.btn_state.set_name("btnState")
121
+ self.btn_state.connect("clicked", self.show_state)
122
+ self.btn_state.set_tooltip_text("If green all good. Click to see commnets and defects.")
122
123
 
123
124
  grid.attach(Gtk.Label(label="Serial No."), 0, 0, 1, 1)
124
125
  grid.attach(self.SN, 1, 0, 1, 1)
@@ -221,6 +222,44 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
221
222
 
222
223
  self.show_all()
223
224
 
225
+
226
+ def show_state(self, *arg):
227
+ """Shows the status"""
228
+ msg = ""
229
+ for test in self.test_list:
230
+ values = test.values
231
+ ndef = len(values["defects"])
232
+ ncomm = len(values["comments"])
233
+ if ndef==0 and ncomm==0:
234
+ continue
235
+
236
+ msg += "{}\n".format(values["testType"])
237
+ if ndef:
238
+ msg += "Defects\n"
239
+
240
+ for D in values["defects"]:
241
+ msg += "{}: {}\n".format(D["name"], D["description"])
242
+
243
+ if ncomm:
244
+ msg += "Comments\n"
245
+
246
+ for C in values["comments"]:
247
+ msg += "{}\n".format(C)
248
+
249
+ msg += "\n"
250
+
251
+ dialog = Gtk.MessageDialog(
252
+ transient_for=self,
253
+ flags=0,
254
+ message_type=Gtk.MessageType.INFO,
255
+ buttons=Gtk.ButtonsType.OK,
256
+ text="Problems found",
257
+ )
258
+
259
+ dialog.format_secondary_text(msg)
260
+ dialog.run()
261
+ dialog.destroy()
262
+
224
263
  def on_reset(self, *args):
225
264
  """Reset SN"""
226
265
  self.petal_core = None
@@ -669,7 +708,7 @@ class AVSPanel(dbGtkUtils.ITkDBWindow):
669
708
  for test in self.test_list:
670
709
  values = test.values
671
710
  self.write_message("{}\n".format(values["testType"]))
672
- res = ITkDButils.upload_test(self.session, values)
711
+ res = ITkDButils.upload_test(self.session, values, check_runNumber=True)
673
712
  if res is not None:
674
713
  dbGtkUtils.complain("Could not upload test {}".format(values["testType"]), res)
675
714
 
@@ -218,7 +218,7 @@ class UploadTest(dbGtkUtils.ITkDBWindow):
218
218
 
219
219
  except TypeError:
220
220
  self.load_payload(self.payload)
221
- self.write_message("Loaded memory payload.")
221
+ self.write_message("Loaded memory payload.\n")
222
222
 
223
223
  if len(self.attachments) > 0:
224
224
  self.btn_attch.set_label("Attachments ({})".format(len(self.attachments)))
@@ -2,7 +2,10 @@
2
2
  """Wirebonding GUI for PSB."""
3
3
 
4
4
  import sys
5
+ import re
5
6
  import json
7
+ import copy
8
+ from pathlib import Path
6
9
  import gi
7
10
 
8
11
  gi.require_version("Gtk", "3.0")
@@ -12,7 +15,6 @@ try:
12
15
  import itkdb_gtk
13
16
 
14
17
  except ImportError:
15
- from pathlib import Path
16
18
  cwd = Path(__file__).parent.parent
17
19
  sys.path.append(cwd.as_posix())
18
20
  import itkdb_gtk
@@ -22,6 +24,23 @@ __HELP_LINK__="https://itkdb-gtk.docs.cern.ch/wirebondTest.html"
22
24
  from itkdb_gtk import dbGtkUtils
23
25
  from itkdb_gtk import ITkDBlogin, ITkDButils, UploadTest
24
26
 
27
+
28
+ #valid_channel = re.compile("(^[0-9]+)-([0-9]+)")
29
+ valid_channel = re.compile("^[0-9]+[\\s*\\,\\s,-[0-9]+]*")
30
+
31
+ def range_to_list(V):
32
+ """Convert a range (ch1-ch2) to a list."""
33
+ if '-' not in V:
34
+ return [V]
35
+
36
+ out = []
37
+ endpoints = list(map(int, V.split('-')))
38
+ endpoints.sort()
39
+ for i in range(endpoints[0], endpoints[1]+1):
40
+ out.append(str(i))
41
+
42
+ return out
43
+
25
44
  test_parameters = {
26
45
  "Repaired Row 1": "REPAIRED_FRONTEND_ROW1",
27
46
  "Failed Row 1": "FAILED_FRONTEND_ROW1",
@@ -422,12 +441,14 @@ class WireBond(dbGtkUtils.ITkDBWindow):
422
441
  self.pdb = None
423
442
  self.models = {}
424
443
  self.holes = {}
425
- self.institute = "IFIC"
444
+ self.institute = self.pdb_user["institutions"][0]["code"]
426
445
  self.inst_combo = None
427
446
  self.module_SN = None
428
447
  self.alternativeID = None
429
448
  self.combo = None
430
449
  self.tree = None
450
+ self.lut = {}
451
+ self.module_type = None
431
452
  self.init_window()
432
453
 
433
454
  def init_window(self):
@@ -464,15 +485,31 @@ class WireBond(dbGtkUtils.ITkDBWindow):
464
485
  grid = Gtk.Grid(column_spacing=5, row_spacing=1)
465
486
 
466
487
  # The shipment receiver
467
- institute = self.create_institute_combo()
488
+ institute = self.create_institute_combo(True)
468
489
  institute.connect("changed", self.on_institute)
469
490
  institute.set_tooltip_text("Select the Institute.")
470
491
  dbGtkUtils.set_combo_iter(institute, self.institute)
471
- grid.attach(Gtk.Label(label="Institute"), 0, 0, 1, 1)
492
+
493
+ lbl = Gtk.Label(label="Institute")
494
+ lbl.set_xalign(0)
495
+ grid.attach(lbl, 0, 0, 1, 1)
472
496
  grid.attach(institute, 1, 0, 1, 1)
473
497
  self.inst_combo = institute
474
498
 
475
499
 
500
+
501
+ # The lookup table
502
+ lbl = Gtk.Label(label="Lookup Table")
503
+ lbl.set_xalign(0)
504
+ grid.attach(lbl, 2, 0, 1, 1)
505
+
506
+ self.testF = Gtk.FileChooserButton()
507
+ self.testF.set_tooltip_text("Click to select Lookup table.")
508
+
509
+ grid.attach(self.testF, 3, 0, 1, 1)
510
+ self.testF.connect("file-set", self.on_lut)
511
+
512
+
476
513
  for i, tit in enumerate(["Operator", "Bond Machine", "Wire Batch", "SN", "Date"]):
477
514
  lbl = Gtk.Label(label=tit)
478
515
  lbl.set_xalign(0)
@@ -514,7 +551,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
514
551
  box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
515
552
  self.mainBox.pack_start(box, False, False, 0)
516
553
  dbGtkUtils.add_button_to_container(box, "Add Bond",
517
- "Click to add a new bond.",
554
+ "Click to add a new bond or bond range.",
518
555
  self.add_item)
519
556
 
520
557
  dbGtkUtils.add_button_to_container(box, "Remove Bond",
@@ -527,6 +564,75 @@ class WireBond(dbGtkUtils.ITkDBWindow):
527
564
  self.mainBox.pack_start(self.message_panel.frame, True, True, 0)
528
565
  self.write_message("wirebond GUI\n")
529
566
 
567
+ def on_lut(self, fdlg):
568
+ """Get look-up table."""
569
+ fnam = Path(fdlg.get_filename())
570
+ if not fnam.exists():
571
+ dbGtkUtils.complain("Cannot open Luukup Table.",
572
+ "File {} does not exist.".format(fnam))
573
+ return
574
+
575
+ lut = {}
576
+ module_map = {}
577
+ section = None
578
+ with open(fnam, 'r', encoding="UTF-8") as fin:
579
+ for line in fin:
580
+ line = line.strip()
581
+
582
+ # Remove comments.
583
+ ipos = line.find('#')
584
+ if ipos >= 0:
585
+ line = line[:ipos].strip()
586
+
587
+ if len(line) == 0:
588
+ continue
589
+
590
+ # Check for new section
591
+ ipos = line.find(':')
592
+ if ipos >= 0:
593
+ section = line[:ipos].strip().upper()
594
+ if section in module_map:
595
+ dbGtkUtils.complain("Section {} already in map.".format(section), "Stop parsing bond Lookup table.")
596
+ return
597
+
598
+ lut = {}
599
+ module_map[section] = lut
600
+ continue
601
+
602
+ if section is None:
603
+ continue
604
+
605
+ values = list(map(str.strip, line.split(',')))
606
+ if len(values)!=2:
607
+ dbGtkUtils.complain("Cannot read Lookup table.", "Wrong line format: {}".format(line))
608
+ return
609
+
610
+ v_local = range_to_list(values[0])
611
+ v_std = range_to_list(values[1])
612
+
613
+ if len(v_local) != len(v_std):
614
+ dbGtkUtils.complain("Wrong Lookup table.",
615
+ "Ranges have different length: {}".format(line))
616
+ return
617
+
618
+ for L, S in zip(v_local, v_std):
619
+ lut[L] = S
620
+
621
+ self.lut = module_map
622
+
623
+ def convert_channel(self, C):
624
+ """Convert channel according to LUT
625
+
626
+ Args:
627
+ C (str): channel number
628
+
629
+ """
630
+ try:
631
+ return self.lut[self.module_type][C]
632
+
633
+ except KeyError:
634
+ return C
635
+
530
636
  def on_institute(self, combo):
531
637
  """Institute changed."""
532
638
  name = self.get_institute_from_combo(combo)
@@ -536,13 +642,20 @@ class WireBond(dbGtkUtils.ITkDBWindow):
536
642
  def on_SN_changed(self, entry, value):
537
643
  """New SN given. Ask in PDB,"""
538
644
  if len(value) <= 0:
539
- return None
540
-
645
+ return
541
646
 
542
647
  obj = itkdb_gtk.ITkDButils.get_DB_component(self.session, value)
543
- if obj is not None:
648
+ if obj is not None and obj["serialNumber"] is not None:
544
649
  entry.set_text(obj["serialNumber"])
545
- self.alternativeID = obj["alternativeIdentifier"]
650
+ alternativeID = obj["alternativeIdentifier"]
651
+ module_SN = obj["serialNumber"]
652
+ if len(module_SN) == 14 and module_SN.startswith("20USEM"):
653
+ self.module_SN = module_SN
654
+ self.alternativeID = alternativeID
655
+ self.module_type = module_SN[5:7]
656
+
657
+ else:
658
+ itkdb_gtk.dbGtkUtils.complain("Invalid SN: {}".format(module_SN), "Not a Ring module")
546
659
 
547
660
  else:
548
661
  itkdb_gtk.dbGtkUtils.complain("Invalid SN", value)
@@ -620,8 +733,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
620
733
  def channel_edited(self, widget, path, text):
621
734
  """Handles edition in channel number cell."""
622
735
  if not text.isnumeric():
623
- dbGtkUtils.complain("Wrong channel number", "Invalid channel number: {}".format(text))
624
- return
736
+ if valid_channel.match(text) is None:
737
+ dbGtkUtils.complain("Wrong channel number", "Invalid channel number: {}".format(text))
738
+ return
625
739
 
626
740
  self.text_edited(0, path, text)
627
741
 
@@ -705,6 +819,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
705
819
  param = get_module_param(self.SN.get_text())
706
820
  except ValueError as E:
707
821
  dbGtkUtils.complain("Wrong SN number", str(E))
822
+ return None
708
823
 
709
824
  M = ModuleHoles(param=param)
710
825
 
@@ -766,6 +881,9 @@ class WireBond(dbGtkUtils.ITkDBWindow):
766
881
  def get_unconnected(self, skeleton):
767
882
  """Fill the test DTO with unconnected information."""
768
883
  out = self.compute_unconnected()
884
+ if out is None:
885
+ raise ValueError("Wrong SN")
886
+
769
887
  for key, val in out.items():
770
888
  skeleton["results"][key] = val
771
889
 
@@ -832,6 +950,47 @@ class WireBond(dbGtkUtils.ITkDBWindow):
832
950
 
833
951
  data["results"][key] = out
834
952
 
953
+ def fix_list_of_channels(self, data):
954
+ """Expand ranges and, eventually, apply LUT.
955
+
956
+ Args:
957
+ data: The test payload.
958
+ """
959
+ for tit, section in data["results"].items():
960
+ if not isinstance(section, dict):
961
+ continue
962
+
963
+ range_items = []
964
+ added_items = []
965
+ for key, comment in section.items():
966
+ values = list(map(str.strip, key.split(',')))
967
+ if ',' in key or '-' in key:
968
+ range_items.append(key)
969
+
970
+ else:
971
+ continue
972
+
973
+ for V in values:
974
+ if '-' in V:
975
+ for i in range_to_list(V):
976
+ added_items.append((str(i), comment))
977
+
978
+ elif len(V)>0:
979
+ added_items.append((V, comment))
980
+
981
+ for key in range_items:
982
+ section.pop(key)
983
+
984
+ for key, comm in added_items:
985
+ section[key] = comm
986
+
987
+ if len(self.lut)>0 and len(section)>0:
988
+ tmp = copy.deepcopy(section)
989
+ section.clear()
990
+ for key, val in tmp.items():
991
+ section[self.convert_channel(key)] = val
992
+
993
+
835
994
  def save_test(self, *args):
836
995
  """Save Test file."""
837
996
  dialog = Gtk.FileChooserDialog(
@@ -863,6 +1022,7 @@ class WireBond(dbGtkUtils.ITkDBWindow):
863
1022
  data = {
864
1023
  "institution": self.institute,
865
1024
  "date": ITkDButils.get_db_date(),
1025
+ "runNumber": "1",
866
1026
  "properties": {},
867
1027
  "results": {},
868
1028
  "comments": [],
@@ -927,7 +1087,12 @@ class WireBond(dbGtkUtils.ITkDBWindow):
927
1087
 
928
1088
  self.get_test_header(skeleton)
929
1089
  self.get_list_of_channels(skeleton)
930
- self.get_unconnected(skeleton)
1090
+ self.fix_list_of_channels(skeleton)
1091
+ try:
1092
+ self.get_unconnected(skeleton)
1093
+
1094
+ except ValueError:
1095
+ return
931
1096
 
932
1097
  uploadW = UploadTest.UploadTest(self.session, payload=skeleton)
933
1098
  # uploadW.run()
@@ -1,6 +1,6 @@
1
1
  """ itkdb-gtk python module
2
2
  """
3
- __version__ = "0.10.9.dev4"
3
+ __version__ = "0.10.10.dev2"
4
4
 
5
5
 
6
6
  def dash_board():
@@ -1,4 +1,5 @@
1
1
  """A set of GTK utilities for DB scripts."""
2
+ import sys
2
3
  import json
3
4
  import time
4
5
  import pathlib
@@ -18,6 +19,16 @@ gi.require_version("Gtk", "3.0")
18
19
  from gi.repository import Gtk, GObject, Gio, GLib
19
20
 
20
21
 
22
+ try:
23
+ import itkdb_gtk
24
+
25
+ except ImportError:
26
+ cwd = pathlib.Path(__file__).parent.parent
27
+ sys.path.append(cwd.as_posix())
28
+
29
+ from itkdb_gtk import ITkDButils
30
+
31
+
21
32
  def setup_scanner(callback):
22
33
  """Setup scanner and callback function."""
23
34
  for fnam in ["/dev/ttyACM0", "/dev/cu.usbmodemS_N_G19F204881"]:
@@ -51,9 +62,10 @@ def parse_date(txt):
51
62
  try:
52
63
  return dateutil.parser.parse(txt, fuzzy=False)
53
64
 
54
- except Exception:
65
+ except dateutil.parser.ParserError:
55
66
  return None
56
67
 
68
+
57
69
  def parse_date_as_string(txt):
58
70
  """Parse data and return DB compatible string."""
59
71
  D = parse_date(txt)
@@ -76,7 +88,7 @@ def is_a_date(txt):
76
88
  dateutil.parser.parse(txt, fuzzy=False)
77
89
  return True
78
90
 
79
- except Exception:
91
+ except (dateutil.parser.ParserError, OverflowError):
80
92
  return False
81
93
 
82
94
  def new_small_text_entry():
@@ -223,7 +235,6 @@ def ask_for_confirmation(main_title, second_text, parent=None):
223
235
  dialog.destroy()
224
236
  return (out == Gtk.ResponseType.OK)
225
237
 
226
-
227
238
  class TextEntry(GObject.GObject):
228
239
  """Create a Gtk text entry/view object."""
229
240
  __gsignals__ = {
@@ -235,6 +246,7 @@ class TextEntry(GObject.GObject):
235
246
  GObject.GObject.__init__(self)
236
247
  self.tmp_txt = ""
237
248
  self.nlines = n_lines
249
+ self.do_emit = True
238
250
  if self.nlines > 1:
239
251
  self.widget = Gtk.Frame()
240
252
  scrolled = Gtk.ScrolledWindow()
@@ -254,12 +266,11 @@ class TextEntry(GObject.GObject):
254
266
 
255
267
  self.widget.connect("focus-in-event", self.on_enter)
256
268
  self.widget.connect("focus-out-event", self.on_leave)
257
-
258
269
  self.entry = self.widget
259
270
 
260
271
  def do_my_signal(self, *args):
261
272
  """Signal handler."""
262
- pass
273
+ return
263
274
 
264
275
  def on_enter(self, *args):
265
276
  """On enter."""
@@ -270,7 +281,9 @@ class TextEntry(GObject.GObject):
270
281
  """On leave."""
271
282
  val = self.widget.get_text().strip()
272
283
  if val != self.tmp_txt:
284
+ self.do_emit = False
273
285
  self.emit("text_changed", val)
286
+ self.do_emit = True
274
287
 
275
288
  def get_text(self):
276
289
  """Return the text."""
@@ -285,11 +298,17 @@ class TextEntry(GObject.GObject):
285
298
 
286
299
  def set_text(self, text):
287
300
  """Sets text."""
301
+ if text is None:
302
+ return
303
+
288
304
  if self.nlines > 1:
289
305
  self.entry.get_buffer().set_text(text)
290
306
  else:
291
307
  self.entry.set_text(text)
292
-
308
+ if self.do_emit:
309
+ self.do_emit = False
310
+ self.emit("text_changed", text)
311
+ self.do_emit = True
293
312
 
294
313
  def get_a_value(main_title, second_text=None, is_tv=False, parent=None):
295
314
  """Open a dialog to get a value.
@@ -304,7 +323,7 @@ def get_a_value(main_title, second_text=None, is_tv=False, parent=None):
304
323
  value: The value in the entry
305
324
 
306
325
  """
307
- dlg = Gtk.Dialog(title="Add Attachment",
326
+ dlg = Gtk.Dialog(title="Get a Value",
308
327
  transient_for=parent,
309
328
  flags=0)
310
329
  dlg.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
@@ -385,7 +404,8 @@ def get_a_list_of_values(main_title, labels, defaults=None, second_text=None, pa
385
404
  entry = TextEntry(3 if use_tv else -1)
386
405
  try:
387
406
  entry.set_text(defaults[i])
388
- except Exception:
407
+
408
+ except (TypeError, IndexError):
389
409
  pass
390
410
 
391
411
  vbox.pack_start(entry.widget, False, False, 0)
@@ -510,6 +530,7 @@ class ITkDBWindow(Gtk.Window):
510
530
  self.code2inst = {}
511
531
  self.message_panel = None
512
532
  self.help = help_link
533
+ self.pdb_user = ITkDButils.get_db_user(self.session)
513
534
 
514
535
  if gtk_runs:
515
536
  super().__init__(title=title)
@@ -552,12 +573,13 @@ class ITkDBWindow(Gtk.Window):
552
573
  self.mainBox.set_property("margin-left", 6)
553
574
  self.mainBox.set_property("margin-right", 6)
554
575
 
576
+ self.title_label = None
555
577
  if len(title)>0:
556
578
  lbl = Gtk.Label()
557
579
  lbl.set_markup("<big><b>{}\n</b></big>".format(title))
558
580
  lbl.set_xalign(0.5)
559
- self.mainBox.pack_start(lbl, True, True, 2)
560
-
581
+ self.mainBox.pack_start(lbl, False, False, 2)
582
+ self.title_label = lbl
561
583
 
562
584
  self.add(self.mainBox)
563
585
 
@@ -573,6 +595,13 @@ class ITkDBWindow(Gtk.Window):
573
595
 
574
596
  self.mainBox.pack_end(btnBox, False, True, 0)
575
597
 
598
+ def set_window_title(self, title):
599
+ """Set window title."""
600
+ hb = self.get_titlebar()
601
+ hb.props.title = title
602
+ if self.title_label:
603
+ self.title_label.set_markup("<big><b>{}\n</b></big>".format(title))
604
+
576
605
  def quit(self, *args):
577
606
  """Quits the application."""
578
607
  self.hide()
@@ -584,7 +613,7 @@ class ITkDBWindow(Gtk.Window):
584
613
 
585
614
  def query_db(self, *args):
586
615
  """Search button clicked."""
587
- pass
616
+ return
588
617
 
589
618
  def new_login(self, obj, msg):
590
619
  """A new user logged in."""
@@ -603,18 +632,32 @@ class ITkDBWindow(Gtk.Window):
603
632
  if hasattr(self.session, "user_gui"):
604
633
  self.session.user_gui.reconnect(force=True)
605
634
 
606
- def create_institute_combo(self):
607
- """Create a combe with all institutes."""
608
- compltn = self.get_institute_list()
635
+ def create_institute_combo(self, only_user=False):
636
+ """Create a combe with all institutes.
637
+
638
+ Args:
639
+ only_user: if True, add only institutes the user belongs to.
640
+
641
+ """
642
+ compltn = self.get_institute_list(only_user)
609
643
  combo = Gtk.ComboBox.new_with_model_and_entry(compltn.get_model())
610
644
  combo.set_entry_text_column(0)
611
645
  combo.get_child().set_completion(compltn)
612
646
 
613
647
  return combo
614
648
 
615
- def get_institute_list(self):
616
- """Get the institute list."""
617
- sites = self.session.get("listInstitutions", json={})
649
+ def get_institute_list(self, only_user=False):
650
+ """Get the institute list.
651
+
652
+ Args:
653
+ only_user: if True, add only institutes the user belongs to.
654
+
655
+ """
656
+ if only_user and self.pdb_user:
657
+ sites = self.pdb_user["institutions"]
658
+ else:
659
+ sites = self.session.get("listInstitutions", json={})
660
+
618
661
  liststore = Gtk.ListStore(str, str)
619
662
  for site in sites:
620
663
  self.code2inst[site['code']] = site['name']
@@ -367,7 +367,7 @@ def check_for_problems(sheet, the_test, row_range):
367
367
  reason = cell_value(sheet, "i{}".format(row))
368
368
 
369
369
  if reason:
370
- if len(reason) < 20:
370
+ if len(reason) < 1:
371
371
  msg = "{}: {}".format(hdr, reason)
372
372
  the_test["defects"].append({"name": msg})
373
373
  else:
@@ -395,7 +395,7 @@ def readFATfile(session, file_path, SN=None):
395
395
  """
396
396
  # Open spreadsheet
397
397
  try:
398
- wb = XL.load_workbook(file_path)
398
+ wb = XL.load_workbook(file_path, data_only=True)
399
399
  except InvalidFileException as ee:
400
400
  print("Could not open input file: ", file_path)
401
401
  print(ee)
@@ -566,7 +566,7 @@ def readProductionSheet(session, file_path, SN):
566
566
 
567
567
  """
568
568
  try:
569
- wb = XL.load_workbook(file_path)
569
+ wb = XL.load_workbook(file_path, data_only=True)
570
570
  except InvalidFileException as ee:
571
571
  print("Could not open input file: ", file_path)
572
572
  print(ee.message)
@@ -688,6 +688,6 @@ if __name__ == "__main__":
688
688
  sys.exit()
689
689
 
690
690
  fnam = Path(options.files[0]).expanduser().resolve()
691
- # readProductionSheet(fnam, options.SN)
692
- readFATfile(client, fnam, options.SN)
691
+ readProductionSheet(client, fnam, options.SN)
692
+ # readFATfile(client, fnam, options.SN)
693
693
  dlg.die()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: itkdb_gtk
3
- Version: 0.10.9.dev4
3
+ Version: 0.10.10.dev2
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
@@ -31,6 +31,7 @@ itkdb_gtk.egg-info/entry_points.txt
31
31
  itkdb_gtk.egg-info/requires.txt
32
32
  itkdb_gtk.egg-info/top_level.txt
33
33
  test/testAnimated.py
34
+ test/testBatch.py
34
35
  test/testComponent.py
35
36
  test/test_attachment.py
36
37
  test/test_holes.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "itkdb_gtk"
7
- version = "0.10.9.dev4"
7
+ version = "0.10.10.dev2"
8
8
  authors = [
9
9
  { name="Carlos Lacasta", email="carlos.lacasta@cern.ch" },
10
10
  ]
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """Test Batches."""
3
+
4
+ try:
5
+ import itkdb_gtk
6
+
7
+ except ImportError:
8
+ import sys
9
+ from pathlib import Path
10
+ cwd = Path(__file__).parent.parent
11
+ sys.path.append(cwd.as_posix())
12
+
13
+ from itkdb_gtk import ITkDBlogin, ITkDButils
14
+
15
+
16
+ def get_all_Petals(session):
17
+ """Find all petal cores"""
18
+ # find all cores
19
+ # Now all the objects
20
+ payload = {
21
+ "filterMap": {
22
+ #"componentType": ["BT"],
23
+ "componentType": ["CORE_PETAL"],
24
+ "type": ["CORE_AVS"],
25
+ #"currentLocation": ["IFIC"],
26
+ },
27
+ "sorterList": [
28
+ {"key": "alternativeIdentifier", "descending": False }
29
+ ],
30
+ }
31
+ core_list = session.get("listComponents", json=payload)
32
+ return core_list
33
+
34
+ def list_petal_core_batches(session):
35
+ """Get list of Petal core batches"""
36
+ payload = {
37
+ "project": "S",
38
+ "batchType": ["PETAL_CORE_PROTO", "PETAL_CORE_PREPROD", "PETAL_CORE_PROD"],
39
+ }
40
+ batch_list = session.get("listBatches", json=payload)
41
+ rc = {}
42
+ for B in batch_list:
43
+ rc[B["code"] ]= B["id"]
44
+
45
+ return rc
46
+
47
+
48
+
49
+ def main(session):
50
+ batch_list = list_petal_core_batches(session)
51
+
52
+ # # create the batches
53
+ # for bc, bid in batch_list.items():
54
+ # payload = {
55
+ # "project": "S",
56
+ # "batchType": bc,
57
+ # "number": "1",
58
+ # "ownerInstituteList": ["AVS", "IFIC", "DESYHH"]
59
+ # }
60
+ # rc = session.post("createBatch", json=payload)
61
+
62
+
63
+ for petal_core in get_all_Petals(session):
64
+ aliasID = petal_core["alternativeIdentifier"]
65
+ if "PPB" in aliasID:
66
+ batch_code = "PETAL_CORE_PREPROD"
67
+ elif "PPC" in aliasID:
68
+ batch_code = "PETAL_CORE_PROD"
69
+ elif "test" in aliasID.lower():
70
+ continue
71
+ else:
72
+ batch_code = "PETAL_CORE_PROTO"
73
+
74
+ print("{} - {}".format(aliasID, batch_code))
75
+ rc = session.post("addBatchComponent", json={"id":batch_list[batch_code], "component": petal_core["id"]})
76
+
77
+
78
+ if __name__ == "__main__":
79
+ # ITk_PB authentication
80
+ dlg = ITkDBlogin.ITkDBlogin()
81
+ session = dlg.get_client()
82
+
83
+ try:
84
+ main(session)
85
+
86
+ except Exception as E:
87
+ print(E)