PaIRS-UniNa 0.2.5__cp313-cp313-win_amd64.whl → 0.2.6__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of PaIRS-UniNa might be problematic. Click here for more details.
- PaIRS_UniNa/Changes.txt +14 -2
- PaIRS_UniNa/Explorer.py +10 -6
- PaIRS_UniNa/Input_Tab.py +5 -2
- PaIRS_UniNa/Input_Tab_CalVi.py +4 -4
- PaIRS_UniNa/Input_Tab_tools.py +4 -3
- PaIRS_UniNa/PaIRS_pypacks.py +182 -56
- PaIRS_UniNa/Process_Tab.py +2 -2
- PaIRS_UniNa/Process_Tab_Disp.py +1 -1
- PaIRS_UniNa/Saving_tools.py +7 -7
- PaIRS_UniNa/TabTools.py +7 -4
- PaIRS_UniNa/Vis_Tab.py +57 -38
- PaIRS_UniNa/Whatsnew.py +11 -0
- PaIRS_UniNa/_PaIRS_PIV.pyd +0 -0
- PaIRS_UniNa/__init__.py +3 -3
- PaIRS_UniNa/gPaIRS.py +111 -31
- PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
- PaIRS_UniNa/icons/pencil_bw.png +0 -0
- PaIRS_UniNa/pivParFor.py +1 -1
- PaIRS_UniNa/rqrdpckgs.txt +6 -5
- PaIRS_UniNa/stereoPivParFor.py +1 -1
- PaIRS_UniNa/ui_gPairs.py +9 -3
- PaIRS_UniNa/whatsnew.txt +3 -4
- {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.6.dist-info}/METADATA +24 -19
- {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.6.dist-info}/RECORD +26 -24
- {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.6.dist-info}/WHEEL +0 -0
- {pairs_unina-0.2.5.dist-info → pairs_unina-0.2.6.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/Changes.txt
CHANGED
|
@@ -1,4 +1,16 @@
|
|
|
1
|
-
********* Changes in version 0.2.
|
|
1
|
+
********* Changes in version 0.2.6 (2025.09.06) **********
|
|
2
|
+
Bug fixes:
|
|
3
|
+
- fixed bugs related to process tree management.
|
|
4
|
+
|
|
5
|
+
User-interface enhancements:
|
|
6
|
+
- enhanced release check using SSL for reliable retrieval of the latest version.
|
|
7
|
+
|
|
8
|
+
Distribution:
|
|
9
|
+
- ready-to-use executables of PaIRS are now available!
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
********* Changes in version 0.2.5 (2025.07.28) **********
|
|
2
14
|
Bug fixes:
|
|
3
15
|
- fixed bugs in launching PIV and stereoscopic PIV processes in special cases;
|
|
4
16
|
- fixed tooltip crash introduced by PySide 6.9;
|
|
@@ -17,7 +29,7 @@ User-interface enhancements:
|
|
|
17
29
|
|
|
18
30
|
Distribution:
|
|
19
31
|
- Support for Python 3.9 has been discontinued;
|
|
20
|
-
- Python 3.13 builds have been successfully created and tested.
|
|
32
|
+
- Python 3.13 builds have been successfully created and tested in Windows.
|
|
21
33
|
|
|
22
34
|
|
|
23
35
|
|
PaIRS_UniNa/Explorer.py
CHANGED
|
@@ -1318,7 +1318,7 @@ class ProcessTree(PaIRSTree):
|
|
|
1318
1318
|
par.ind[1]=int(self.FlagBin)
|
|
1319
1319
|
par.ind[2]=i
|
|
1320
1320
|
except Exception as inst:
|
|
1321
|
-
pri.Error.red(inst)
|
|
1321
|
+
pri.Error.red(f"{inst}\n{traceback.format_exc()}")
|
|
1322
1322
|
pass
|
|
1323
1323
|
if hasattr(self.gui,'setLinks'):
|
|
1324
1324
|
inds_new_list=list(inds_new)
|
|
@@ -1383,7 +1383,7 @@ class ProcessTree(PaIRSTree):
|
|
|
1383
1383
|
if self.FlagExternalDrag:
|
|
1384
1384
|
self.FlagExternalDrag=False
|
|
1385
1385
|
self.dragged_items=None
|
|
1386
|
-
self.setStyleSheet(
|
|
1386
|
+
self.setStyleSheet(self.initialStyleSheet)
|
|
1387
1387
|
if self.parent(): self.setPalette(self.parent().palette())
|
|
1388
1388
|
self.hovered_item=None
|
|
1389
1389
|
|
|
@@ -1424,7 +1424,7 @@ class ProcessTree(PaIRSTree):
|
|
|
1424
1424
|
if not self.widgets: return
|
|
1425
1425
|
for w in self.widgets:
|
|
1426
1426
|
w:gPaIRS_Tab
|
|
1427
|
-
w.gen_TABpar(ITE.ind,FlagEmptyPrev=True,FlagInsert=
|
|
1427
|
+
w.gen_TABpar(ITE.ind,FlagEmptyPrev=True,FlagInsert=2,Process=ITE.Process,Step=ITE.Step)
|
|
1428
1428
|
pass
|
|
1429
1429
|
return
|
|
1430
1430
|
|
|
@@ -1434,11 +1434,11 @@ class ProcessTree(PaIRSTree):
|
|
|
1434
1434
|
if t in self.widgetNames:
|
|
1435
1435
|
k=self.widgetNames.index(t)
|
|
1436
1436
|
w:gPaIRS_Tab=self.widgets[k]
|
|
1437
|
-
w.gen_TABpar(ITE.ind,FlagInsert=
|
|
1437
|
+
w.gen_TABpar(ITE.ind,FlagInsert=3,Process=ITE.Process,Step=ITE.Step)
|
|
1438
1438
|
pass
|
|
1439
1439
|
for w, wn in zip(self.widgets,self.widgetNames):
|
|
1440
1440
|
if wn not in ITE.tabs+['TabArea']:
|
|
1441
|
-
w.gen_TABpar(ITE.ind,FlagNone=True,FlagInsert=
|
|
1441
|
+
w.gen_TABpar(ITE.ind,FlagNone=True,FlagInsert=3,Process=ITE.Process,Step=ITE.Step)
|
|
1442
1442
|
pass
|
|
1443
1443
|
return
|
|
1444
1444
|
|
|
@@ -1697,10 +1697,14 @@ class ProcessTree(PaIRSTree):
|
|
|
1697
1697
|
if errorString:
|
|
1698
1698
|
if '_data' in filename:
|
|
1699
1699
|
try:
|
|
1700
|
+
errorString=''
|
|
1700
1701
|
basename,ext=os.path.splitext(filename)
|
|
1701
1702
|
filename2=basename[:-5]+ext
|
|
1702
1703
|
data, errorMessage=loadList(filename2)
|
|
1703
|
-
errorString=errorString+errorMessage if errorMessage else ''
|
|
1704
|
+
#errorString=errorString+errorMessage if errorMessage else ''
|
|
1705
|
+
if errorMessage:
|
|
1706
|
+
WarningMessage="It was not possible to determine which process the selected data file belongs to.\nPlease, try again by loading the process output file directly."
|
|
1707
|
+
warningDialog(self,WarningMessage)
|
|
1704
1708
|
except Exception as inst2:
|
|
1705
1709
|
errorString+=str(inst2)
|
|
1706
1710
|
FlagError=True
|
PaIRS_UniNa/Input_Tab.py
CHANGED
|
@@ -197,6 +197,7 @@ class Input_Tab(gPaIRS_Tab):
|
|
|
197
197
|
|
|
198
198
|
self.ImTreeInd=[]
|
|
199
199
|
self.ui.imTreeWidget.imTree.signals.stopWorker.connect(self.emptyImTreeInd)
|
|
200
|
+
self.ui.imTreeWidget.FlagInGui=True
|
|
200
201
|
|
|
201
202
|
self.FlagScanPath=False
|
|
202
203
|
pri.Time.yellow('Input: define callbacks')
|
|
@@ -312,10 +313,10 @@ class Input_Tab(gPaIRS_Tab):
|
|
|
312
313
|
|
|
313
314
|
self.ui.spin_inp_ncam.setEnabled(self.INPpar.FlagCam)
|
|
314
315
|
self.ui.spin_inp_ncam.setMinimum(self.ncamMinimum())
|
|
315
|
-
self.ui.imTreeWidget.spin_ncam.setEnabled(
|
|
316
|
+
self.ui.imTreeWidget.spin_ncam.setEnabled(False)
|
|
316
317
|
self.ui.imTreeWidget.FlagCam=self.INPpar.FlagCam
|
|
317
318
|
self.ui.imTreeWidget.spin_ncam.setMinimum(self.ncamMinimum())
|
|
318
|
-
self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.
|
|
319
|
+
self.ui.imTreeWidget.spin_ncam.setValue(self.INPpar.importPar.inp_ncam)
|
|
319
320
|
self.ui.spin_inp_cam.setEnabled(self.INPpar.inp_ncam>1)
|
|
320
321
|
self.ui.spin_inp_cam.setMaximum(self.INPpar.inp_ncam)
|
|
321
322
|
self.setImageNumberSpinLimits()
|
|
@@ -418,6 +419,8 @@ class Input_Tab(gPaIRS_Tab):
|
|
|
418
419
|
self.ui.line_edit_path.setText(currpath)
|
|
419
420
|
self.INPpar.path=self.ui.line_edit_path.text()
|
|
420
421
|
self.line_edit_path_preaction()
|
|
422
|
+
else:
|
|
423
|
+
currpath='./'
|
|
421
424
|
|
|
422
425
|
def button_path_action_future(self):
|
|
423
426
|
self.line_edit_path_action_future()
|
PaIRS_UniNa/Input_Tab_CalVi.py
CHANGED
|
@@ -311,7 +311,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
|
|
|
311
311
|
|
|
312
312
|
def line_edit_cameras_action(self):
|
|
313
313
|
text=self.ui.line_edit_cameras.text()
|
|
314
|
-
split_text=re.findall('(\d+)', text)
|
|
314
|
+
split_text=re.findall(r'(\d+)', text)
|
|
315
315
|
self.INPpar.cams=[]
|
|
316
316
|
for s in split_text:
|
|
317
317
|
i=int(s)
|
|
@@ -365,7 +365,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
|
|
|
365
365
|
f=os.path.basename(filename)
|
|
366
366
|
FlagWarn=False
|
|
367
367
|
if self.INPpar.FlagCam:
|
|
368
|
-
fsplitted=re.split('_cam\d+', f)
|
|
368
|
+
fsplitted=re.split(r'_cam\d+', f)
|
|
369
369
|
if len(fsplitted)>1:
|
|
370
370
|
fsplitted.insert(-1,'_cam*')
|
|
371
371
|
f="".join(fsplitted)
|
|
@@ -508,7 +508,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
|
|
|
508
508
|
if self.INPpar.FlagCam and len(self.INPpar.cams)==0:
|
|
509
509
|
ncam=0
|
|
510
510
|
for f in self.INPpar.filenames:
|
|
511
|
-
pats=re.findall('_cam\d+', f)
|
|
511
|
+
pats=re.findall(r'_cam\d+', f)
|
|
512
512
|
if len(pats):
|
|
513
513
|
ncam=int(pats[-1].replace("_cam",""))
|
|
514
514
|
break
|
|
@@ -534,7 +534,7 @@ class Input_Tab_CalVi(gPaIRS_Tab):
|
|
|
534
534
|
if self.INPpar.FlagCam:
|
|
535
535
|
for k,f in enumerate(self.INPpar.filenames):
|
|
536
536
|
if '_cam*' in f: continue
|
|
537
|
-
fsplitted=re.split('_cam\d+', f)
|
|
537
|
+
fsplitted=re.split(r'_cam\d+', f)
|
|
538
538
|
fsplitted.insert(-1,'_cam*')
|
|
539
539
|
f="".join(fsplitted)
|
|
540
540
|
self.INPpar.filenames[k]=f
|
PaIRS_UniNa/Input_Tab_tools.py
CHANGED
|
@@ -104,7 +104,7 @@ class ImageSet(TABpar):
|
|
|
104
104
|
|
|
105
105
|
def addPattern(self,basename):
|
|
106
106
|
_, ext = os.path.splitext(basename)
|
|
107
|
-
split_basename=re.split('(\d+)', basename)
|
|
107
|
+
split_basename=re.split(r'(\d+)', basename)
|
|
108
108
|
c=0
|
|
109
109
|
for k,s in enumerate(split_basename):
|
|
110
110
|
if not len(s): continue
|
|
@@ -172,7 +172,7 @@ class ImageSet(TABpar):
|
|
|
172
172
|
while i<len(jl) and p2[diff[0]]<l[i]: i+=1
|
|
173
173
|
jl.insert(i-1,j)
|
|
174
174
|
l.insert(i-1,p2[diff[0]])
|
|
175
|
-
self.link[k]=jalpha+jnumber+[k]
|
|
175
|
+
self.link[k]=jalpha+sorted(jnumber)+[k]
|
|
176
176
|
return
|
|
177
177
|
|
|
178
178
|
def print(self):
|
|
@@ -1604,6 +1604,7 @@ class ImageTreeWidget(QWidget):
|
|
|
1604
1604
|
self.signals=self.ImageTreeWidget_signals()
|
|
1605
1605
|
self.FlagSpinButtons=FlagSpinButtons
|
|
1606
1606
|
self.FlagCam=True
|
|
1607
|
+
self.FlagInGui=False
|
|
1607
1608
|
|
|
1608
1609
|
font=self.font()
|
|
1609
1610
|
font.setItalic(True)
|
|
@@ -2208,7 +2209,7 @@ class ImageTreeWidget(QWidget):
|
|
|
2208
2209
|
self.spin_cam.setStatusTip(self.spin_cam.toolTip())
|
|
2209
2210
|
FlagSingleTree=type(self.imTree)==SingleImageTree
|
|
2210
2211
|
self.spin_cam.setEnabled(self.imTree.ncam>1 and (self.imTree.nimg>1 or FlagSingleTree))
|
|
2211
|
-
self.spin_ncam.setEnabled(not FlagSingleTree and self.FlagCam)
|
|
2212
|
+
self.spin_ncam.setEnabled(not FlagSingleTree and self.FlagCam and not self.FlagInGui)
|
|
2212
2213
|
|
|
2213
2214
|
self.spin_frame.setToolTip(f'Current frame. Number of frames: {self.spin_frame.maximum()}')
|
|
2214
2215
|
self.spin_frame.setStatusTip(self.spin_frame.toolTip())
|
PaIRS_UniNa/PaIRS_pypacks.py
CHANGED
|
@@ -15,10 +15,12 @@ basefold_DEBUG='./'
|
|
|
15
15
|
basefold_DEBUG_VIS=''
|
|
16
16
|
#basefold='B:/dl/apairs/jetcross'
|
|
17
17
|
|
|
18
|
+
|
|
18
19
|
developerIDs={
|
|
19
20
|
'GP_Win_Office': '231128824800632', #'0x7824af430781',
|
|
20
21
|
'GP_Win_Office_New': '140626882900161', #'0x7824af430781',
|
|
21
22
|
'GP_Mac_Laptop': 'V94LRP93FV', #'0xa275dd445ab0',
|
|
23
|
+
'GP_WSL' : 'b44ec1c0e5a74ffd97bb050c39ef6cb1',
|
|
22
24
|
'TA_Win_Office': '160983906000941', #'0xccb0da8c896e'
|
|
23
25
|
'TA_Win_Office_New': '231128824801036', #??
|
|
24
26
|
}
|
|
@@ -29,9 +31,32 @@ def getCurrentID():
|
|
|
29
31
|
serial_number=None
|
|
30
32
|
try:
|
|
31
33
|
if psutil.LINUX:
|
|
34
|
+
def get_linux_serial():
|
|
35
|
+
from pathlib import Path
|
|
36
|
+
candidates = [
|
|
37
|
+
Path("/sys/class/dmi/id/board_serial"),
|
|
38
|
+
Path("/sys/class/dmi/id/product_uuid"),
|
|
39
|
+
Path("/etc/machine-id"), Path("/var/lib/dbus/machine-id") #WSL
|
|
40
|
+
]
|
|
41
|
+
for p in candidates:
|
|
42
|
+
try:
|
|
43
|
+
if p.is_file():
|
|
44
|
+
val = p.read_text(errors="ignore").strip()
|
|
45
|
+
if val and val.lower() not in {
|
|
46
|
+
"none", "unknown", "not specified", "to be filled by o.e.m."
|
|
47
|
+
}:
|
|
48
|
+
return val
|
|
49
|
+
except Exception as e:
|
|
50
|
+
if Flag_DEBUG:
|
|
51
|
+
print(f"Error while retrieving motherboard serial number: {e}")
|
|
52
|
+
continue
|
|
53
|
+
return None
|
|
54
|
+
serial_number = get_linux_serial()
|
|
55
|
+
""""
|
|
32
56
|
# On Linux, the motherboard serial number can be obtained from the /sys/class/dmi/id/board_serial file
|
|
33
57
|
with open('/sys/class/dmi/id/board_serial', 'r') as f:
|
|
34
58
|
serial_number = f.read().strip()
|
|
59
|
+
"""
|
|
35
60
|
elif psutil.WINDOWS:
|
|
36
61
|
# On Windows, the motherboard serial number can be obtained using WMI
|
|
37
62
|
output = subprocess.check_output(["wmic", "baseboard", "get", "SerialNumber"]).decode('utf-8')
|
|
@@ -43,7 +68,8 @@ def getCurrentID():
|
|
|
43
68
|
if b'Serial Number (system)' in line:
|
|
44
69
|
serial_number = line.split(b':')[1].strip().decode('utf-8')
|
|
45
70
|
except Exception as e:
|
|
46
|
-
|
|
71
|
+
if Flag_DEBUG:
|
|
72
|
+
print(f"Error while retrieving motherboard serial number: {e}")
|
|
47
73
|
return serial_number
|
|
48
74
|
|
|
49
75
|
currentID=getCurrentID()
|
|
@@ -58,6 +84,16 @@ if currentID in (developerIDs['GP_Win_Office'],developerIDs['GP_Win_Office_New']
|
|
|
58
84
|
'C:/desk/PIV_Img/_data/Calibration_data/cylinder/',
|
|
59
85
|
]
|
|
60
86
|
basefold_DEBUG_VIS='C:/desk/PIV_Img/_data/PIV_data/real_case/'
|
|
87
|
+
elif currentID==developerIDs['GP_WSL']:
|
|
88
|
+
basefold_DEBUG='/mnt/c/desk/PIV_Img/_data/PIV_data/virtual_case/'
|
|
89
|
+
basefold_DEBUGOptions=[
|
|
90
|
+
'/mnt/c/desk/PIV_Img/img1/',
|
|
91
|
+
'/mnt/c/desk/PIV_Img/_data/PIV_data/virtual_case/',
|
|
92
|
+
'/mnt/c/desk/PIV_Img/_data/PIV_data/real_case/',
|
|
93
|
+
'/mnt/c/desk/PIV_Img/_data/Calibration_data/pinhole/',
|
|
94
|
+
'/mnt/c/desk/PIV_Img/_data/Calibration_data/cylinder/',
|
|
95
|
+
]
|
|
96
|
+
basefold_DEBUG_VIS='/mnt/c/desk/PIV_Img/_data/PIV_data/real_case/'
|
|
61
97
|
elif currentID==developerIDs['GP_Mac_Laptop']: #gerardo mac
|
|
62
98
|
basefold_DEBUG='/Users/gerardo/Desktop/PIV_Img/swirler_png/' #'/Users/gerardo/Desktop/PIV_Img/img1/'
|
|
63
99
|
basefold_DEBUGOptions=[
|
|
@@ -72,12 +108,12 @@ elif currentID==developerIDs['GP_Mac_Laptop']: #gerardo mac
|
|
|
72
108
|
basefold_DEBUG_VIS='/Users/gerardo/Desktop/PaIRS_examples/PIV_data/real_case/'
|
|
73
109
|
basefold_DEBUG_VIS='/Users/gerardo/Desktop/PIV_Img/img1/'
|
|
74
110
|
elif currentID in (developerIDs['TA_Win_Office'],developerIDs['TA_Win_Office_New']): #TA windows
|
|
75
|
-
basefold_DEBUG='C:\desk\Attuali\PythonLibC\PIV\img'
|
|
111
|
+
basefold_DEBUG=r'C:\desk\Attuali\PythonLibC\PIV\img'
|
|
76
112
|
basefold_DEBUGOptions=[
|
|
77
113
|
'C:/desk/PIV_Img/img1/',
|
|
78
114
|
'C:/desk/PIV_Img/swirler_png/',
|
|
79
115
|
'../../img/calib/',
|
|
80
|
-
'C:\desk\Attuali\PythonLibC\PIV\img',
|
|
116
|
+
r'C:\desk\Attuali\PythonLibC\PIV\img',
|
|
81
117
|
]
|
|
82
118
|
basefold_DEBUG_VIS=''
|
|
83
119
|
else:
|
|
@@ -149,6 +185,37 @@ import sys
|
|
|
149
185
|
import concurrent.futures
|
|
150
186
|
import asyncio
|
|
151
187
|
|
|
188
|
+
_old_init_QAction = QAction.__init__
|
|
189
|
+
def _new_init_QAction(self, *args, **kwargs):
|
|
190
|
+
_old_init_QAction(self, *args, **kwargs)
|
|
191
|
+
try:
|
|
192
|
+
self.setIconVisibleInMenu(True)
|
|
193
|
+
except Exception:
|
|
194
|
+
pass
|
|
195
|
+
QAction.__init__ = _new_init_QAction
|
|
196
|
+
_old_init_QMenu = QMenu.__init__
|
|
197
|
+
def _new_init_QMenu(self, *args, **kwargs):
|
|
198
|
+
_old_init_QMenu(self, *args, **kwargs)
|
|
199
|
+
try:
|
|
200
|
+
self.menuAction().setIconVisibleInMenu(True)
|
|
201
|
+
except Exception:
|
|
202
|
+
pass
|
|
203
|
+
QMenu.__init__ = _new_init_QMenu
|
|
204
|
+
|
|
205
|
+
# --- Patch dei metodi QMenu che CREANO/AGGIUNGONO azioni (copre gli overload C++) ---
|
|
206
|
+
_old_addAction = QMenu.addAction
|
|
207
|
+
def _new_addAction(self, *args, **kwargs):
|
|
208
|
+
act:QAction = _old_addAction(self, *args, **kwargs) # può essere creato lato C++
|
|
209
|
+
try:
|
|
210
|
+
if isinstance(act, QAction):
|
|
211
|
+
act.setIconVisibleInMenu(True)
|
|
212
|
+
except Exception:
|
|
213
|
+
pass
|
|
214
|
+
return act
|
|
215
|
+
QMenu.addAction = _new_addAction
|
|
216
|
+
|
|
217
|
+
Flag_ISEXE=getattr(sys, 'frozen', False) #made by pyInstaller
|
|
218
|
+
EXEurl='https://www.pairs.unina.it/#download'
|
|
152
219
|
|
|
153
220
|
class ColorPrint:
|
|
154
221
|
def __init__(self,flagTime=False,prio=PrintTAPriority.medium,faceStd=PrintTA.faceStd,flagFullDebug=False):
|
|
@@ -184,6 +251,7 @@ class GPaIRSPrint:
|
|
|
184
251
|
self.Info=ColorPrint(prio=PrintTAPriority.medium)
|
|
185
252
|
self.Time=ColorPrint(prio=PrintTAPriority.medium if FlagPrintTime else PrintTAPriority.veryLow,flagTime=True,faceStd=PrintTA.faceUnderline)
|
|
186
253
|
self.Error=ColorPrint(prio=PrintTAPriority.medium,faceStd=PrintTA.faceBold)
|
|
254
|
+
self.IOError=ColorPrint(prio=PrintTAPriority.veryLow,faceStd=PrintTA.faceBold)
|
|
187
255
|
self.Process=ColorPrint(prio=PrintTAPriority.veryLow)
|
|
188
256
|
self.Callback=ColorPrint(prio=PrintTAPriority.veryLow)
|
|
189
257
|
self.TABparDiff=ColorPrint(prio=PrintTAPriority.veryLow)
|
|
@@ -237,7 +305,6 @@ if __package__ or "." in __name__:
|
|
|
237
305
|
foldPaIRS = foldPaIRS.replace('\\', '/')
|
|
238
306
|
else:
|
|
239
307
|
foldPaIRS='./'
|
|
240
|
-
|
|
241
308
|
class ProcessTypes:
|
|
242
309
|
null=None
|
|
243
310
|
min=0
|
|
@@ -247,7 +314,7 @@ class ProcessTypes:
|
|
|
247
314
|
cal=10
|
|
248
315
|
|
|
249
316
|
singleCamera=[piv]
|
|
250
|
-
threeCameras=[tpiv]
|
|
317
|
+
threeCameras=[min,tpiv]
|
|
251
318
|
|
|
252
319
|
class StepTypes:
|
|
253
320
|
null=None
|
|
@@ -291,15 +358,24 @@ class outExt:
|
|
|
291
358
|
cfg_calvi='.calvi_cfg'
|
|
292
359
|
pla='.pairs_pla'
|
|
293
360
|
|
|
294
|
-
|
|
295
361
|
|
|
296
362
|
lastcfgname='lastWorkSpace'+outExt.wksp
|
|
297
|
-
|
|
298
363
|
fileChanges=foldPaIRS+'Changes.txt'
|
|
299
|
-
fileWhatsNew=[foldPaIRS+f for f in fileWhatsNew]
|
|
300
364
|
icons_path=foldPaIRS+icons_path
|
|
301
|
-
|
|
302
|
-
|
|
365
|
+
|
|
366
|
+
if not Flag_ISEXE:
|
|
367
|
+
fileWhatsNew=[foldPaIRS+f for f in fileWhatsNew]
|
|
368
|
+
|
|
369
|
+
lastcfgname=foldPaIRS+lastcfgname
|
|
370
|
+
pro_path=foldPaIRS+"pro/"
|
|
371
|
+
else:
|
|
372
|
+
from pathlib import Path
|
|
373
|
+
exe_dir = str(Path(sys.argv[0]).resolve().parent)+'/'
|
|
374
|
+
fileWhatsNew=[foldPaIRS+fileWhatsNew[0],exe_dir+fileWhatsNew[1]]
|
|
375
|
+
lastcfgname = exe_dir + lastcfgname
|
|
376
|
+
pro_path = exe_dir + "pro/"
|
|
377
|
+
|
|
378
|
+
|
|
303
379
|
if not os.path.exists(pro_path):
|
|
304
380
|
try:
|
|
305
381
|
os.mkdir(pro_path)
|
|
@@ -782,12 +858,16 @@ def runPaIRS(self,command='',flagQuestion=True):
|
|
|
782
858
|
def run(self):
|
|
783
859
|
try:
|
|
784
860
|
import subprocess
|
|
785
|
-
if
|
|
786
|
-
pri.Info.white(sys.executable+'
|
|
787
|
-
subprocess.call(sys.executable+'
|
|
861
|
+
if Flag_ISEXE:
|
|
862
|
+
pri.Info.white(sys.executable+' '+command)
|
|
863
|
+
subprocess.call(sys.executable+' '+command,shell=True)
|
|
788
864
|
else:
|
|
789
|
-
|
|
790
|
-
|
|
865
|
+
if Flag: #launched from package
|
|
866
|
+
pri.Info.white(sys.executable+' -m PaIRS_UniNa '+command)
|
|
867
|
+
subprocess.call(sys.executable+' -m PaIRS_UniNa '+command,shell=True)
|
|
868
|
+
else:
|
|
869
|
+
pri.Info.white(sys.executable+' -c '+'"'+f"import os; os.chdir('{os.getcwd()}'); {pyCommands[command]}"+'"')
|
|
870
|
+
subprocess.call(sys.executable+' -c '+'"'+f"import os; os.chdir('{os.getcwd()}'); {pyCommands[command]}"+'"',shell=True)
|
|
791
871
|
self.isRunning=False
|
|
792
872
|
except Exception as inst:
|
|
793
873
|
pri.Error.red(inst)
|
|
@@ -816,12 +896,12 @@ def showSplash(filename=''+ icons_path +'logo_PaIRS_completo.png'):
|
|
|
816
896
|
splash.show()
|
|
817
897
|
return splash
|
|
818
898
|
|
|
819
|
-
def checkLatestVersion(self,version,app:QApplication=None,splash:QLabel=None):
|
|
899
|
+
def checkLatestVersion(self,version,app:QApplication=None,splash:QLabel=None,flagWarning=1):
|
|
820
900
|
flagStopAndDownload=False
|
|
821
901
|
var=self.TABpar
|
|
822
902
|
#var.FlagOutDated=0 if currentVersion==var.latestVersion else var.FlagOutDated
|
|
823
903
|
if abs(var.FlagOutDated)==1:
|
|
824
|
-
warningLatestVersion(self,app,flagExit=0,flagWarning=
|
|
904
|
+
warningLatestVersion(self,app,flagExit=0,flagWarning=flagWarning,FlagStayOnTop=True)
|
|
825
905
|
var.FlagOutDated=2 if var.FlagOutDated==1 else -2
|
|
826
906
|
"""
|
|
827
907
|
flagStopAndDownload=questionDialog(self,f'A new version of the PaIRS_UniNa package is available. Do you want to download it before starting the current istance of {self.name}?')
|
|
@@ -852,7 +932,7 @@ def checkLatestVersion(self,version,app:QApplication=None,splash:QLabel=None):
|
|
|
852
932
|
var.FlagOutDated=-2 if var.FlagOutDated==-2 else -1
|
|
853
933
|
elif flagOutDated==-1000:
|
|
854
934
|
sOut=f'Error from pip: it was not possible to check for a new version of the {packageName} package!'
|
|
855
|
-
var.FlagOutDated
|
|
935
|
+
var.FlagOutDated=-1000
|
|
856
936
|
else:
|
|
857
937
|
sOut=f'{packageName} The current version ({currentVersion}) of {packageName} is up-to-date! Enjoy it!'
|
|
858
938
|
var.FlagOutDated=0
|
|
@@ -872,13 +952,18 @@ def warningLatestVersion(self,app,flagExit=0,flagWarning=0,time_milliseconds=0,F
|
|
|
872
952
|
py=myStandardRoot(sys.executable).split('/')[-1].split('.')[0]
|
|
873
953
|
command=f'{py} -m pip install --upgrade PaIRS_UniNa'
|
|
874
954
|
if self.TABpar.FlagOutDated>0:
|
|
875
|
-
|
|
955
|
+
if Flag_ISEXE:
|
|
956
|
+
Message=f'A new version of the PaIRS_UniNa package is available (current: {self.TABpar.currentVersion}, latest: {self.TABpar.latestVersion}).\nPlease, download it from the following link:\n{EXEurl}'
|
|
957
|
+
else:
|
|
958
|
+
Message=f'A new version of the PaIRS_UniNa package is available (current: {self.TABpar.currentVersion}, latest: {self.TABpar.latestVersion}).\nPlease, {exitSuggestion}install it with the following command:\n{command}'
|
|
959
|
+
elif self.TABpar.FlagOutDated==-1000:
|
|
960
|
+
Message = ("Unable to check for the latest official release of PaIRS_UniNa. Please check the PyPI page manually for updates:\n""https://pypi.org/project/PaIRS-UniNa/")
|
|
876
961
|
else:
|
|
877
962
|
Message=f'The version of the current instance of PaIRS_UniNa ({self.TABpar.currentVersion}) is newer than the latest official releas ({self.TABpar.latestVersion})!\nYou should contact Tommaso and Gerardo if you are a developer and some relevant change is made by yourself!\nIf you are a user, enjoy this beta version and please report any issue!'
|
|
878
963
|
if flagExit:
|
|
879
964
|
print(f"\n{'*'*100}\n"+Message+f"\n{'*'*100}\n")
|
|
880
965
|
if flagWarning:
|
|
881
|
-
warningDialog(self,Message,time_milliseconds=time_milliseconds,flagScreenCenter=True,pixmap=''+ icons_path +'flaticon_PaIRS_download.png' if self.TABpar.FlagOutDated>0 else ''+ icons_path +'flaticon_PaIRS_beta.png',FlagStayOnTop=FlagStayOnTop,addButton={"See what's new!": lambda: QDesktopServices.openUrl(QUrl("https://pypi.org/project/PaIRS-UniNa/"))} if self.TABpar.FlagOutDated>0 else {})
|
|
966
|
+
warningDialog(self,Message,time_milliseconds=time_milliseconds,flagScreenCenter=True,pixmap=''+ icons_path +'flaticon_PaIRS_download.png' if self.TABpar.FlagOutDated>0 else ''+ icons_path +'flaticon_PaIRS_download_warning.png' if self.TABpar.FlagOutDated==-1000 else ''+ icons_path +'flaticon_PaIRS_beta.png',FlagStayOnTop=FlagStayOnTop,addButton={"Go to the download page!": lambda: QDesktopServices.openUrl(QUrl(EXEurl))} if Flag_ISEXE else {"See what's new!": lambda: QDesktopServices.openUrl(QUrl("https://pypi.org/project/PaIRS-UniNa/"))} if self.TABpar.FlagOutDated>0 else {})
|
|
882
967
|
|
|
883
968
|
def downloadLatestVersion(self,app):
|
|
884
969
|
try:
|
|
@@ -902,6 +987,7 @@ def downloadLatestVersion(self,app):
|
|
|
902
987
|
|
|
903
988
|
def button_download_PaIRS_action(self,app):
|
|
904
989
|
warningLatestVersion(self,app,flagExit=0,flagWarning=1)
|
|
990
|
+
checkLatestVersion(self,__version__,self.app,splash=None,flagWarning=0)
|
|
905
991
|
return
|
|
906
992
|
flagStopAndDownload=questionDialog(self,f'A new version of the PaIRS_UniNa package is available. Do you want to close the current instance of {self.name} and download it?')
|
|
907
993
|
if not flagStopAndDownload: return
|
|
@@ -913,6 +999,20 @@ def button_download_PaIRS_action(self,app):
|
|
|
913
999
|
else: command=''
|
|
914
1000
|
subprocess.call(sys.executable+' -m PaIRS_UniNa '+command,shell=True)
|
|
915
1001
|
#runPaIRS(self,flagQuestion=False)
|
|
1002
|
+
|
|
1003
|
+
import urllib.request, json, ssl
|
|
1004
|
+
|
|
1005
|
+
def get_package_version_urllib(package_name):
|
|
1006
|
+
"""Get package version using only standard library"""
|
|
1007
|
+
try:
|
|
1008
|
+
import certifi
|
|
1009
|
+
url = f"https://pypi.org/pypi/{package_name}/json"
|
|
1010
|
+
context = ssl.create_default_context(cafile=certifi.where())
|
|
1011
|
+
with urllib.request.urlopen(url, context=context, timeout=10) as response:
|
|
1012
|
+
data = json.loads(response.read().decode())
|
|
1013
|
+
return True, data['info']['version']
|
|
1014
|
+
except Exception as e:
|
|
1015
|
+
return False, f"Error: {e}"
|
|
916
1016
|
|
|
917
1017
|
def checkOutDated(packageName:str,printOutDated):
|
|
918
1018
|
'''
|
|
@@ -944,48 +1044,60 @@ def checkOutDated(packageName:str,printOutDated):
|
|
|
944
1044
|
currentVersion='none'
|
|
945
1045
|
latestVersion=''
|
|
946
1046
|
try:
|
|
947
|
-
if
|
|
1047
|
+
if Flag_ISEXE:
|
|
948
1048
|
currentVersion=__version__+'.'+__subversion__ if int(__subversion__) else __version__
|
|
949
1049
|
else:
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1050
|
+
if Flag_DEBUG:
|
|
1051
|
+
currentVersion=__version__+'.'+__subversion__ if int(__subversion__) else __version__
|
|
1052
|
+
else:
|
|
1053
|
+
command=[sys.executable, '-m', 'pip', 'show', packageName]
|
|
1054
|
+
reqs = subprocess.run(command,capture_output=True)
|
|
1055
|
+
if reqs.returncode:
|
|
1056
|
+
pri.Error.red('Error in command:\n'+' '.join(command)+'\n'+reqs.stderr.decode("utf-8") )
|
|
1057
|
+
return flagOutDated,currentVersion,latestVersion
|
|
1058
|
+
printing=reqs.stdout.decode("utf-8")
|
|
1059
|
+
pri.Info.cyan( printing )
|
|
1060
|
+
r=reqs.stdout.decode("utf-8").replace('\r','').split('\n')
|
|
1061
|
+
currentVersion='none'
|
|
1062
|
+
for s in r:
|
|
1063
|
+
if 'Version: ' in s:
|
|
1064
|
+
currentVersion=s.replace('Version: ','')
|
|
1065
|
+
break
|
|
963
1066
|
if currentVersion!=__version__:
|
|
964
1067
|
message=f'Greetings, developer!\nThe version of the current instance of PaIRS_UniNa ({__version__}) is different from that installed in the present Python environment ({currentVersion})!\nYou should contact Tommaso and Gerardo if some relevant change is made by yourself!'
|
|
965
1068
|
pri.Info.yellow(f'{"-"*50}\n{message}\n{"-"*50}\n')
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
if not reqs.returncode:
|
|
969
|
-
printing=reqs.stdout.decode("utf-8")
|
|
970
|
-
pri.Info.cyan( printing )
|
|
971
|
-
r=reqs.stdout.decode("utf-8").replace('\r','').split('\n')
|
|
972
|
-
#currentVersion=r[0].replace(packageName,'').replace('(','').replace(')','').replace(' ','')
|
|
973
|
-
latestVersion=r[1].replace('Available versions: ','').split(',')[0]
|
|
1069
|
+
if Flag_ISEXE:
|
|
1070
|
+
_, latestVersion = get_package_version_urllib("PaIRS_UniNa")
|
|
974
1071
|
else:
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
command=[sys.executable, '-m', 'pip', 'list','--outdated']
|
|
1072
|
+
command=[sys.executable, '-m', 'pip', 'index', 'versions', packageName]
|
|
978
1073
|
reqs = subprocess.run(command,capture_output=True)
|
|
979
|
-
if reqs.returncode:
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
latestVersion=outDated[i+2]
|
|
1074
|
+
if not reqs.returncode:
|
|
1075
|
+
printing=reqs.stdout.decode("utf-8")
|
|
1076
|
+
pri.Info.cyan( printing )
|
|
1077
|
+
r=reqs.stdout.decode("utf-8").replace('\r','').split('\n')
|
|
1078
|
+
#currentVersion=r[0].replace(packageName,'').replace('(','').replace(')','').replace(' ','')
|
|
1079
|
+
latestVersion=r[1].replace('Available versions: ','').split(',')[0]
|
|
986
1080
|
else:
|
|
987
|
-
latestVersion=
|
|
988
|
-
|
|
1081
|
+
flagOk,latestVersion=get_package_version_urllib(packageName)
|
|
1082
|
+
if not flagOk:
|
|
1083
|
+
pri.Error.red('Error in command:\n'+' '.join(command)+'\n'+reqs.stderr.decode("utf-8") )
|
|
1084
|
+
pri.Error.red(latestVersion)
|
|
1085
|
+
latestVersion='none'
|
|
1086
|
+
|
|
1087
|
+
"""
|
|
1088
|
+
command=[sys.executable, '-m', 'pip', 'list','--outdated']
|
|
1089
|
+
reqs = subprocess.run(command,capture_output=True)
|
|
1090
|
+
if reqs.returncode:
|
|
1091
|
+
pri.Error.red('Error in command:\n'+' '.join(command)+'\n'+reqs.stderr.decode("utf-8") )
|
|
1092
|
+
return flagOutDated,currentVersion,latestVersion
|
|
1093
|
+
outDated = [r.decode().split('==')[0] for r in reqs.stdout.split()]
|
|
1094
|
+
if packageName in outDated:
|
|
1095
|
+
i=outDated.index(packageName)
|
|
1096
|
+
latestVersion=outDated[i+2]
|
|
1097
|
+
else:
|
|
1098
|
+
latestVersion=currentVersion
|
|
1099
|
+
pri.Info.cyan(f'{packageName} ({currentVersion}). Latest version available: {latestVersion}')
|
|
1100
|
+
"""
|
|
989
1101
|
#flagOutDated=1 if currentVersion!=latestVersion else 0
|
|
990
1102
|
cV_parts=[int(c) for c in currentVersion.split('.')]
|
|
991
1103
|
lV_parts=[int(c) for c in latestVersion.split('.')]
|
|
@@ -1165,6 +1277,19 @@ def resetRequiredPackagesFile(filename=rqrdpckgs_filename):
|
|
|
1165
1277
|
else:
|
|
1166
1278
|
pri.Error.red(f"resetRequiredPackagesFile: Skipping malformed line: {line}")
|
|
1167
1279
|
|
|
1280
|
+
def to_triplet(v: Version) -> tuple[int,int,int]:
|
|
1281
|
+
r = v.release or (0,)
|
|
1282
|
+
return (r[0], r[1] if len(r) > 1 else 0, r[2] if len(r) > 2 else 0)
|
|
1283
|
+
|
|
1284
|
+
def le_ver(a: Version, b: Version) -> bool:
|
|
1285
|
+
a1,a2,a3 = to_triplet(a)
|
|
1286
|
+
b1,b2,b3 = to_triplet(b)
|
|
1287
|
+
if a1 > b1: return False
|
|
1288
|
+
if a1 < b1: return True
|
|
1289
|
+
if a2 > b2: return False
|
|
1290
|
+
if a2 < b2: return True
|
|
1291
|
+
return a3 <= b3
|
|
1292
|
+
|
|
1168
1293
|
def checkRequiredPackages(self, filename=rqrdpckgs_filename, FlagDisplay=False, FlagForcePrint=False):
|
|
1169
1294
|
required_packages = []
|
|
1170
1295
|
vmin_list = []
|
|
@@ -1199,7 +1324,7 @@ def checkRequiredPackages(self, filename=rqrdpckgs_filename, FlagDisplay=False,
|
|
|
1199
1324
|
Flag = True
|
|
1200
1325
|
|
|
1201
1326
|
# Check if within [vmin, vmax]
|
|
1202
|
-
if not (vmin_list[i]
|
|
1327
|
+
if not (le_ver(vmin_list[i],installed_version) and le_ver(installed_version,vmax_list[i])):
|
|
1203
1328
|
"""
|
|
1204
1329
|
warnings.append(
|
|
1205
1330
|
f"- {pkg}: installed = {installed_version}, target range = [{vmin_list[i]}, {vmax_list[i]}]"
|
|
@@ -1216,7 +1341,8 @@ def checkRequiredPackages(self, filename=rqrdpckgs_filename, FlagDisplay=False,
|
|
|
1216
1341
|
"Some installed packages have a version outside the target range used to develop "
|
|
1217
1342
|
"the current release of the PaIRS_UniNa package.\n\n"
|
|
1218
1343
|
"This may lead to compatibility issues. If you experience unexpected behavior, "
|
|
1219
|
-
"it is recommended to either reinstall the last tested compatible versions
|
|
1344
|
+
"it is recommended to either reinstall the last tested compatible versions or "
|
|
1345
|
+
f"download the executable at {EXEurl}."
|
|
1220
1346
|
f" If any issue occurs, please contact the authors at {__mail__}.\n\n"
|
|
1221
1347
|
#"or use the standalone executable available at:\n"
|
|
1222
1348
|
#"https://pairs.unina.it/#download\n\n"
|
PaIRS_UniNa/Process_Tab.py
CHANGED
|
@@ -724,7 +724,7 @@ class Process_Tab(gPaIRS_Tab):
|
|
|
724
724
|
#******************** Actions
|
|
725
725
|
def edit_Wind_vectors(self,wedit:QLineEdit,wlab:QLabel):
|
|
726
726
|
text=wedit.text()
|
|
727
|
-
split_text=re.split('(\d+)', text)[1:-1:2]
|
|
727
|
+
split_text=re.split(r'(\d+)', text)[1:-1:2]
|
|
728
728
|
vect=[int(i) for i in split_text]
|
|
729
729
|
FlagEmpty=len(vect)==0
|
|
730
730
|
if FlagEmpty: FlagError=True
|
|
@@ -1291,7 +1291,7 @@ class Process_Tab(gPaIRS_Tab):
|
|
|
1291
1291
|
|
|
1292
1292
|
def line_edit_IW_action(self):
|
|
1293
1293
|
text=self.ui.line_edit_IW.text()
|
|
1294
|
-
split_text=re.split('(\d+)', text)[1:-1:2]
|
|
1294
|
+
split_text=re.split(r'(\d+)', text)[1:-1:2]
|
|
1295
1295
|
vect=[int(split_text[i]) for i in (0,2,1,3)]
|
|
1296
1296
|
if len(vect)==4:
|
|
1297
1297
|
k=self.PROpar.row
|
PaIRS_UniNa/Process_Tab_Disp.py
CHANGED
|
@@ -133,7 +133,7 @@ class Process_Tab_Disp(gPaIRS_Tab):
|
|
|
133
133
|
#******************** Actions
|
|
134
134
|
def line_edit_IW_action(self):
|
|
135
135
|
text=self.ui.line_edit_IW.text()
|
|
136
|
-
split_text=re.split('(\d+)', text)[1:-1:2]
|
|
136
|
+
split_text=re.split(r'(\d+)', text)[1:-1:2]
|
|
137
137
|
split_num=[int(t) for t in split_text]
|
|
138
138
|
if len(split_num)<4: split_num+=[split_num[-1]]*(4-len(split_num))
|
|
139
139
|
vect=[int(split_num[i]) for i in (0,2,1,3)]
|