boris-behav-obs 8.26__py2.py3-none-any.whl → 8.27__py2.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.
boris/core.py CHANGED
@@ -53,6 +53,8 @@ import gzip
53
53
  from collections import deque
54
54
 
55
55
  import matplotlib
56
+ import zipfile
57
+ import shutil
56
58
 
57
59
  matplotlib.use("Qt5Agg")
58
60
 
@@ -1360,28 +1362,81 @@ class MainWindow(QMainWindow, Ui_MainWindow):
1360
1362
  def actionCheckUpdate_activated(self, flagMsgOnlyIfNew=False):
1361
1363
  """
1362
1364
  check BORIS web site for updates
1365
+ ask user for updating
1363
1366
  """
1364
1367
 
1368
+ versionURL = "https://www.boris.unito.it/static/ver4.dat"
1365
1369
  try:
1366
- versionURL = "https://www.boris.unito.it/static/ver4.dat"
1367
1370
  last_version = urllib.request.urlopen(versionURL).read().strip().decode("utf-8")
1368
- if util.versiontuple(last_version) > util.versiontuple(__version__):
1369
- msg = (
1370
- f"A new version is available: v. <b>{last_version}</b><br>"
1371
- 'Go to <a href="https://www.boris.unito.it">'
1372
- "https://www.boris.unito.it</a> to install it."
1371
+ except Exception:
1372
+ QMessageBox.warning(self, cfg.programName, "Can not check for updates...")
1373
+ return
1374
+
1375
+ # record check timestamp
1376
+ config_file.save(self, lastCheckForNewVersion=int(time.mktime(time.localtime())))
1377
+
1378
+ if util.versiontuple(last_version) > util.versiontuple(__version__):
1379
+ if (
1380
+ dialog.MessageDialog(
1381
+ cfg.programName,
1382
+ (
1383
+ f"A new version is available: v. {last_version}.<br><br>"
1384
+ 'For updating manually go to <a href="https://www.boris.unito.it">https://www.boris.unito.it</a>.<br>'
1385
+ ),
1386
+ (cfg.CANCEL, "Update automatically"),
1373
1387
  )
1374
- # https://github.com/olivierfriard/BORIS/archive/refs/tags/v{last_version}.zip
1375
- else:
1376
- msg = f"The version you are using is the last one: <b>{__version__}</b>"
1388
+ == cfg.CANCEL
1389
+ ):
1390
+ return
1391
+
1392
+ else:
1393
+ msg = f"The version you are using is the last one: <b>{__version__}</b>"
1394
+ QMessageBox.information(self, cfg.programName, msg)
1395
+
1396
+ # any news?
1377
1397
  newsURL = "https://www.boris.unito.it/static/news.dat"
1378
1398
  news = urllib.request.urlopen(newsURL).read().strip().decode("utf-8")
1379
- config_file.save(self, lastCheckForNewVersion=int(time.mktime(time.localtime())))
1380
- QMessageBox.information(self, cfg.programName, msg)
1381
1399
  if news:
1382
1400
  QMessageBox.information(self, cfg.programName, news)
1401
+ return
1402
+
1403
+ # check if a .git is present
1404
+ if (pl.Path(__file__).parent.parent / pl.Path(".git")).is_dir():
1405
+ QMessageBox.critical(self, cfg.programName, "A .git directory is present, BORIS cannot be automatically updated.")
1406
+ return
1407
+
1408
+ # download zip archive
1409
+ try:
1410
+ zip_content = urllib.request.urlopen(f"https://github.com/olivierfriard/BORIS/archive/refs/tags/v{last_version}.zip").read()
1383
1411
  except Exception:
1384
- QMessageBox.warning(self, cfg.programName, "Can not check for updates...")
1412
+ QMessageBox.critical(self, cfg.programName, "Cannot download the new version")
1413
+ return
1414
+
1415
+ temp_zip = tempfile.NamedTemporaryFile(suffix=".zip")
1416
+ try:
1417
+ with open(temp_zip.name, "wb") as f_out:
1418
+ f_out.write(zip_content)
1419
+ except Exception:
1420
+ QMessageBox.critical(self, cfg.programName, "A problem occurred during saving the new version of BORIS.")
1421
+ return
1422
+
1423
+ # extract to temp dir
1424
+ try:
1425
+ temp_dir = tempfile.TemporaryDirectory()
1426
+ with zipfile.ZipFile(temp_zip.name, "r") as zip_ref:
1427
+ zip_ref.extractall(temp_dir.name)
1428
+ except Exception:
1429
+ QMessageBox.critical(self, cfg.programName, "A problem occurred during the unzip of the new version.")
1430
+ return
1431
+
1432
+ # copy from temp dir to current BORIS dir
1433
+ try:
1434
+ shutil.copytree(f"{temp_dir.name}/BORIS-{last_version}", pl.Path(__file__).parent.parent, dirs_exist_ok=True)
1435
+ except Exception:
1436
+ QMessageBox.critical(self, cfg.programName, "A problem occurred during the copy the new version of BORIS.")
1437
+ return
1438
+
1439
+ QMessageBox.information(self, cfg.programName, f"BORIS was updated to v. {last_version}. Restart the program to apply the changes.")
1385
1440
 
1386
1441
  def seek_mediaplayer(self, new_time: dec, player=0) -> int:
1387
1442
  """
boris/preferences.py CHANGED
@@ -54,7 +54,6 @@ class Preferences(QDialog, Ui_prefDialog):
54
54
  self.pbCancel.clicked.connect(self.reject)
55
55
 
56
56
  self.flag_refresh = False
57
- self.flag_reset_frames_memory = False
58
57
 
59
58
  def refresh_preferences(self):
60
59
  """
boris/select_modifiers.py CHANGED
@@ -43,6 +43,10 @@ from . import utilities as util
43
43
 
44
44
 
45
45
  class ModifiersList(QDialog):
46
+ """
47
+ class for selection the modifier(s)
48
+ """
49
+
46
50
  def __init__(self, code: str, modifiers_dict: dict, currentModifier: str):
47
51
  super().__init__()
48
52
  self.setWindowTitle(cfg.programName)
@@ -60,11 +64,11 @@ class ModifiersList(QDialog):
60
64
  self.modifiersSetNumber = 0
61
65
 
62
66
  for idx in util.sorted_keys(modifiers_dict):
63
- if self.modifiers_dict[idx]["type"] not in [
67
+ if self.modifiers_dict[idx]["type"] not in (
64
68
  cfg.SINGLE_SELECTION,
65
69
  cfg.MULTI_SELECTION,
66
70
  cfg.NUMERIC_MODIFIER,
67
- ]:
71
+ ):
68
72
  continue
69
73
 
70
74
  V2layout = QVBoxLayout()
@@ -75,10 +79,13 @@ class ModifiersList(QDialog):
75
79
  lb.setText(f"Modifier <b>{self.modifiers_dict[idx]['name']}</b>")
76
80
  V2layout.addWidget(lb)
77
81
 
78
- if self.modifiers_dict[idx]["type"] in [
82
+ lb = QLabel(f"<small>{self.modifiers_dict[idx]['description']}</small>")
83
+ V2layout.addWidget(lb)
84
+
85
+ if self.modifiers_dict[idx]["type"] in (
79
86
  cfg.SINGLE_SELECTION,
80
87
  cfg.MULTI_SELECTION,
81
- ]:
88
+ ):
82
89
  lw = QListWidget()
83
90
  self.modifiers_dict[idx]["widget"] = lw
84
91
  lw.setObjectName(f"lw_modifiers_({self.modifiers_dict[idx]['type']})")
@@ -114,6 +121,7 @@ class ModifiersList(QDialog):
114
121
  if self.modifiers_dict[idx]["type"] in [cfg.NUMERIC_MODIFIER]:
115
122
  le = QLineEdit()
116
123
  self.modifiers_dict[idx]["widget"] = le
124
+ le.setObjectName(f"le_modifiers_({self.modifiers_dict[idx]['type']})")
117
125
 
118
126
  if currentModifierList != [""] and currentModifierList[int(idx)] != "None":
119
127
  le.setText(currentModifierList[int(idx)])
@@ -160,10 +168,14 @@ class ModifiersList(QDialog):
160
168
 
161
169
  # accept and close dialog if enter pressed
162
170
  if ek == Qt.Key_Enter or ek == Qt.Key_Return: # enter or enter from numeric pad
163
- self.accept()
171
+ if not self.pbOK_clicked():
172
+ return False
164
173
  return True
165
174
 
175
+ modifiersSetIndex = 0
166
176
  for widget in self.children():
177
+ if "_modifiers" in widget.objectName():
178
+ modifiersSetIndex = modifiersSetIndex + 1
167
179
  if "lw_modifiers" in widget.objectName():
168
180
  if self.modifiersSetNumber == 1:
169
181
  # check if modifiers have code
@@ -172,7 +184,7 @@ class ModifiersList(QDialog):
172
184
  break
173
185
  else:
174
186
  # modifiers have no associated code: the modifier starting with hit key will be selected
175
- if ek not in [Qt.Key_Down, Qt.Key_Up]:
187
+ if ek not in (Qt.Key_Down, Qt.Key_Up):
176
188
  if ek == Qt.Key_Space and f"({cfg.MULTI_SELECTION})" in widget.objectName(): # checking using SPACE bar
177
189
  if widget.item(widget.currentRow()).checkState() == Qt.Checked:
178
190
  widget.item(widget.currentRow()).setCheckState(Qt.Unchecked)
@@ -198,6 +210,7 @@ class ModifiersList(QDialog):
198
210
  return
199
211
 
200
212
  for index in range(widget.count()):
213
+ # check function kesy (F1, F2...)
201
214
  if ek in cfg.function_keys:
202
215
  if f"({cfg.function_keys[ek]})" in widget.item(index).text().upper():
203
216
  if f"({cfg.SINGLE_SELECTION})" in widget.objectName():
@@ -206,6 +219,10 @@ class ModifiersList(QDialog):
206
219
  if self.modifiersSetNumber == 1:
207
220
  self.accept()
208
221
  return True
222
+ # else move to next set of mofifiers
223
+ elif modifiersSetIndex != self.modifiersSetNumber:
224
+ widget.parent().focusNextChild()
225
+ return True
209
226
 
210
227
  if f"({cfg.MULTI_SELECTION})" in widget.objectName():
211
228
  if widget.item(index).checkState() == Qt.Checked:
@@ -220,6 +237,10 @@ class ModifiersList(QDialog):
220
237
  if self.modifiersSetNumber == 1:
221
238
  self.accept()
222
239
  return True
240
+ # else move to next set of mofifiers
241
+ elif modifiersSetIndex != self.modifiersSetNumber:
242
+ widget.parent().focusNextChild()
243
+ return True
223
244
 
224
245
  if f"({cfg.MULTI_SELECTION})" in widget.objectName():
225
246
  if widget.item(index).checkState() == Qt.Checked:
@@ -271,6 +292,9 @@ class ModifiersList(QDialog):
271
292
  return self.modifiers_dict
272
293
 
273
294
  def pbOK_clicked(self):
295
+ """
296
+ OK button is clicked
297
+ """
274
298
  for idx in util.sorted_keys(self.modifiers_dict):
275
299
  if self.modifiers_dict[idx]["type"] == cfg.NUMERIC_MODIFIER:
276
300
  if self.modifiers_dict[idx]["widget"].text():
@@ -280,8 +304,8 @@ class ModifiersList(QDialog):
280
304
  QMessageBox.warning(
281
305
  self,
282
306
  cfg.programName,
283
- "<b>{}</b> is not a numeric value".format(self.modifiers_dict[idx]["widget"].text()),
307
+ f"<b>{self.modifiers_dict[idx]['widget'].text()}</b> is not a numeric value",
284
308
  )
285
- return
309
+ return False
286
310
 
287
311
  self.accept()
boris/version.py CHANGED
@@ -20,5 +20,5 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
- __version__ = "8.26"
24
- __version_date__ = "2024-06-04"
23
+ __version__ = "8.27"
24
+ __version_date__ = "2024-06-06"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: boris-behav-obs
3
- Version: 8.26
3
+ Version: 8.27
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -16,7 +16,7 @@ boris/connections.py,sha256=RIQsaooiz6pzc2jJMHw9CQSyX39TgbM5JAwifCu5eWQ,19280
16
16
  boris/converters.py,sha256=FymqUxLEVLQwsUv6EVF7MRPowN1e87aVT2d3XjZJgAM,11771
17
17
  boris/converters_ui.py,sha256=firMWVgS3c492FF-YFv3FehOBLsbBHKaLEaVcoVctgc,8745
18
18
  boris/cooccurence.py,sha256=scazxKCmFQjBvv7oS9h7ylB8GJdkSmwy1LJZeUv5DOY,9824
19
- boris/core.py,sha256=y_7xvlLojM-Jdu3FlAwzWLQoiiGtHIC2Eo6Qm2SaHhk,222161
19
+ boris/core.py,sha256=xkgkxUjAg-mqXORTQUKKPH8FMRMUkAH7UY8QC1NHeJQ,224211
20
20
  boris/core_qrc.py,sha256=5YMpr7ckI4TbXaeSyCMhNJBAlrGPeLes62RedU3EbWs,865287
21
21
  boris/core_ui.py,sha256=Z_6Ehp93fRVnPGyKRtgX2GcXRXb8QZojXipHSpJ_f3M,69854
22
22
  boris/db_functions.py,sha256=YyI2LMSFn772aMGdkOIpfXbPuoSWEvDckZZKevwvB-4,13326
@@ -58,7 +58,7 @@ boris/plot_events.py,sha256=HAKrdS3qf0A_PG1pGo0FRyk62femDxfxGss3w8CrlUw,23541
58
58
  boris/plot_events_rt.py,sha256=UfO1NKSqBR7j-vnfG8CKuOcdg5o8QQI_0eYdcz29Ufc,8358
59
59
  boris/plot_spectrogram_rt.py,sha256=yc8ifg9HCl-v_upMHkH_rmIZLhWBYkWBOhtKftvRvh0,8394
60
60
  boris/plot_waveform_rt.py,sha256=kNk6NVjM3wT3MpAw5zE9ktH94Pkd2AJ4ppv6uM6BVBc,7502
61
- boris/preferences.py,sha256=5KxUwP10mnsAk8CH3eSlzvd8mtsHsFJfWhzot3QOy3Y,11540
61
+ boris/preferences.py,sha256=W_BHck8lxODvZ9NzIgfvhvXAwUI5A66aJVmdTRTxZMo,11494
62
62
  boris/preferences_ui.py,sha256=LQ46jW9kltJBQD85EHd5cCmlHG4c9N6v6YQLQvUisGM,21935
63
63
  boris/project.py,sha256=i9XT744HoJhlV93C0QuEMD8tNmzIHL0E-iZ4PIOSadc,82219
64
64
  boris/project_functions.py,sha256=R3DS_faDuMGKTpMnV0OhqgZp9yO1ojoA5wUIXdtHNIE,70972
@@ -66,7 +66,7 @@ boris/project_import_export.py,sha256=lCL4fOZuG5MaEf_wfDSHiE7-M2ZQsIbUR7KpHZjb1U
66
66
  boris/project_ui.py,sha256=TRJlsqq4XbIl8k2f20BKr2PtKa0QNjFNr6UnMieZYqU,35915
67
67
  boris/qrc_boris.py,sha256=4U2cD_fIBTtsTPhirOl9I3kTArOhXWYvfuO_A0M9N0I,675001
68
68
  boris/qrc_boris5.py,sha256=6bwT8OVtIr84nVIYp2ldUL7XL6WJi9zgJow6kgRxuIQ,161601
69
- boris/select_modifiers.py,sha256=jbzXKTuAuWnIVsykAuzlQmTqkAcmQsJl7c3cJiPbw_w,12051
69
+ boris/select_modifiers.py,sha256=TAo7xi5bhiMp9WOAwEPq9xc8i4Nsa2QrcpoCrUgPwhE,13178
70
70
  boris/select_observations.py,sha256=snMC23nYD_qi88q95rXqV-NqbGO5BrLrC-CKlmVR3ok,14441
71
71
  boris/select_subj_behav.py,sha256=bX-YCeysK5QowYgoxQyy-9qeZmhzWM4SwArXxSAa5ho,10342
72
72
  boris/state_events.py,sha256=AcZmD0pIJ4AszTQe9conWlh8gJhwdBjZiGm1KOXt804,7768
@@ -76,7 +76,7 @@ boris/time_budget_functions.py,sha256=L-0PuPWYR33UMfqmxpcCVH-w4mLLrtZ8b8kBTmBwls
76
76
  boris/time_budget_widget.py,sha256=9WV-iKYSl1f3HBrGcL-eHDjUswrFQh6-WUcffTtce1Y,42852
77
77
  boris/transitions.py,sha256=2zucdoa2jTpWtM6nWHr8lOvjXkrQmo9j71fz_fMLALU,11998
78
78
  boris/utilities.py,sha256=07qXAQ6aGyiSC2h6RMJ031OlXYy05-KTLJtnQtXn6FU,48724
79
- boris/version.py,sha256=SiBJBuTJeNtnGUhsWns3oikAq4V1gYNKHndPqWMiojY,786
79
+ boris/version.py,sha256=Ehz76ElnqLfCRvK7eQyPLadOAPMH0TDtvJpN74k3_b4,786
80
80
  boris/video_equalizer.py,sha256=QpVgmdqX_E4HnMa2f_Qo_fKJTl9nBoTQd_ykv9RWlIQ,5862
81
81
  boris/video_equalizer_ui.py,sha256=A2_Sz9AAVnJygTRUeK_YXxf-WWQpxSSlFw0MjkxiwSg,9762
82
82
  boris/video_operations.py,sha256=96jR-3snNn9VeEURRD6rCwvOL2sSHXoqlP_gYFwgO8A,9379
@@ -105,9 +105,9 @@ boris/qdarkstyle/utils/__init__.py,sha256=Nlma8-zbHoJc5n2NVT7OvwxPG5765JnsmMeGzr
105
105
  boris/qdarkstyle/utils/__main__.py,sha256=J1biUyDzfutKU1n9NdH9WnD0gFHaF-OJA4Q-n6Q2ehs,3309
106
106
  boris/qdarkstyle/utils/images.py,sha256=af-BJllzWgVoVz6QMvhFcKqvF3mo44AThaBjuAuHtNE,14444
107
107
  boris/qdarkstyle/utils/scss.py,sha256=n7WNo6pPRft8-dU7_gfjB_jA-JZAy50-S792RwR7Ri0,9366
108
- boris_behav_obs-8.26.dist-info/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
109
- boris_behav_obs-8.26.dist-info/METADATA,sha256=nDb9oLy7TwmQToZgmmA3QqO4oPP9gIQE3AxfETicOC0,45541
110
- boris_behav_obs-8.26.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
111
- boris_behav_obs-8.26.dist-info/entry_points.txt,sha256=fuO7JxKFLOm6xp6m3JHRA1UO_QW1dYU-F0IooA1NqQs,37
112
- boris_behav_obs-8.26.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
113
- boris_behav_obs-8.26.dist-info/RECORD,,
108
+ boris_behav_obs-8.27.dist-info/LICENSE.TXT,sha256=WJ7YI-moTFb-uVrFjnzzhGJrnL9P2iqQe8NuED3hutI,35141
109
+ boris_behav_obs-8.27.dist-info/METADATA,sha256=GQwIPQiremyM289rbtZcW7rjDQOlF9X8HfVV5OSsQSo,45541
110
+ boris_behav_obs-8.27.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
111
+ boris_behav_obs-8.27.dist-info/entry_points.txt,sha256=fuO7JxKFLOm6xp6m3JHRA1UO_QW1dYU-F0IooA1NqQs,37
112
+ boris_behav_obs-8.27.dist-info/top_level.txt,sha256=fJSgm62S7WesiwTorGbOO4nNN0yzgZ3klgfGi3Px4qI,6
113
+ boris_behav_obs-8.27.dist-info/RECORD,,