pymodaq 5.0.13__py3-none-any.whl → 5.0.14__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/dashboard.py +12 -54
- {pymodaq-5.0.13.dist-info → pymodaq-5.0.14.dist-info}/METADATA +1 -1
- {pymodaq-5.0.13.dist-info → pymodaq-5.0.14.dist-info}/RECORD +6 -7
- pymodaq/updater.py +0 -107
- {pymodaq-5.0.13.dist-info → pymodaq-5.0.14.dist-info}/WHEEL +0 -0
- {pymodaq-5.0.13.dist-info → pymodaq-5.0.14.dist-info}/entry_points.txt +0 -0
- {pymodaq-5.0.13.dist-info → pymodaq-5.0.14.dist-info}/licenses/LICENSE +0 -0
pymodaq/dashboard.py
CHANGED
|
@@ -79,44 +79,19 @@ class PymodaqUpdateTableWidget(QTableWidget):
|
|
|
79
79
|
'''
|
|
80
80
|
def __init__(self):
|
|
81
81
|
super().__init__()
|
|
82
|
-
|
|
83
|
-
self._checkboxes = []
|
|
84
|
-
self._package_versions = []
|
|
82
|
+
self._row = 0
|
|
85
83
|
|
|
86
84
|
def setHorizontalHeaderLabels(self, labels):
|
|
87
85
|
super().setHorizontalHeaderLabels(labels)
|
|
88
86
|
self.setColumnCount(len(labels))
|
|
89
87
|
|
|
90
|
-
def append_row(self,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
self.
|
|
94
|
-
self.
|
|
95
|
-
|
|
96
|
-
checkbox_widget = QWidget()
|
|
97
|
-
|
|
98
|
-
checkbox.setChecked(True)
|
|
99
|
-
checkbox.setToolTip("Check to install update")
|
|
100
|
-
|
|
101
|
-
checkbox_layout = QtWidgets.QHBoxLayout()
|
|
102
|
-
checkbox_layout.addWidget(checkbox)
|
|
103
|
-
checkbox_layout.setAlignment(Qt.AlignCenter)
|
|
104
|
-
checkbox_layout.setContentsMargins(0, 0, 0, 0)
|
|
105
|
-
|
|
106
|
-
checkbox_widget.setLayout(checkbox_layout)
|
|
88
|
+
def append_row(self, package, current_version, available_version):
|
|
89
|
+
# Add labels
|
|
90
|
+
self.setItem(self._row, 0, QTableWidgetItem(str(package)))
|
|
91
|
+
self.setItem(self._row, 1, QTableWidgetItem(str(current_version)))
|
|
92
|
+
self.setItem(self._row, 2, QTableWidgetItem(str(available_version)))
|
|
107
93
|
|
|
108
|
-
|
|
109
|
-
self.setCellWidget(row, 0, checkbox_widget)
|
|
110
|
-
|
|
111
|
-
# Add labels in the other columns
|
|
112
|
-
self.setItem(row, 1, QTableWidgetItem(str(package)))
|
|
113
|
-
self.setItem(row, 2, QTableWidgetItem(str(current_version)))
|
|
114
|
-
self.setItem(row, 3, QTableWidgetItem(str(available_version)))
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def get_checked_data(self):
|
|
118
|
-
checked = list(map(lambda c : c.isChecked(), self._checkboxes))
|
|
119
|
-
return list(np.array(self._package_versions)[checked])
|
|
94
|
+
self._row += 1
|
|
120
95
|
|
|
121
96
|
def sizeHint(self):
|
|
122
97
|
self.resizeColumnsToContents()
|
|
@@ -1620,11 +1595,10 @@ class DashBoard(CustomApp):
|
|
|
1620
1595
|
available_versions = [version_mod.parse(get_pypi_pymodaq(p)['version']) for p in packages]
|
|
1621
1596
|
new_versions = np.greater(available_versions, current_versions)
|
|
1622
1597
|
# Combine package and version information and select only the ones with a newer version available
|
|
1623
|
-
|
|
1598
|
+
|
|
1624
1599
|
|
|
1625
1600
|
packages_data = np.array(list(zip(packages, current_versions, available_versions)))[new_versions]
|
|
1626
1601
|
|
|
1627
|
-
#TODO: Remove `or True`
|
|
1628
1602
|
if len(packages_data) > 0:
|
|
1629
1603
|
#Create a QDialog window and different graphical components
|
|
1630
1604
|
dialog = QtWidgets.QDialog()
|
|
@@ -1632,43 +1606,27 @@ class DashBoard(CustomApp):
|
|
|
1632
1606
|
|
|
1633
1607
|
vlayout = QtWidgets.QVBoxLayout()
|
|
1634
1608
|
|
|
1635
|
-
message_label = QLabel("New versions of PyMoDAQ packages available!\
|
|
1609
|
+
message_label = QLabel("New versions of PyMoDAQ packages available!\nUse your package manager to update.")
|
|
1636
1610
|
message_label.setAlignment(Qt.AlignCenter)
|
|
1637
1611
|
|
|
1638
1612
|
|
|
1639
1613
|
table = PymodaqUpdateTableWidget()
|
|
1640
1614
|
table.setRowCount(len(packages_data))
|
|
1641
|
-
table.setColumnCount(
|
|
1642
|
-
table.setHorizontalHeaderLabels(["
|
|
1615
|
+
table.setColumnCount(3)
|
|
1616
|
+
table.setHorizontalHeaderLabels(["Package", "Current version", "New version"])
|
|
1643
1617
|
|
|
1644
1618
|
for p in packages_data:
|
|
1645
|
-
table.append_row(
|
|
1619
|
+
table.append_row(p[0], p[1], p[2])
|
|
1646
1620
|
|
|
1647
|
-
button = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
1648
|
-
button.accepted.connect(dialog.accept)
|
|
1649
|
-
button.rejected.connect(dialog.reject)
|
|
1650
1621
|
|
|
1651
1622
|
# The vlayout contains the message, the table and the buttons
|
|
1652
1623
|
# and is connected to the dialog window
|
|
1653
1624
|
vlayout.addWidget(message_label)
|
|
1654
1625
|
vlayout.addWidget(table)
|
|
1655
|
-
vlayout.addWidget(button)
|
|
1656
1626
|
dialog.setLayout(vlayout)
|
|
1657
1627
|
|
|
1658
1628
|
ret = dialog.exec()
|
|
1659
1629
|
|
|
1660
|
-
if ret == QDialog.Accepted:
|
|
1661
|
-
# If the update is accepted, the checked packages are extracted from the table
|
|
1662
|
-
# and send to the updater
|
|
1663
|
-
packages_to_update = table.get_checked_data()
|
|
1664
|
-
if len(packages_to_update) > 0:
|
|
1665
|
-
packages_to_update_str = ', '.join(packages_to_update)
|
|
1666
|
-
logger.info("Trying to update:")
|
|
1667
|
-
logger.info(f"\t {packages_to_update_str}")
|
|
1668
|
-
subprocess.Popen(['pymodaq_updater', '--wait', '--file', __file__] + packages_to_update, stdin=subprocess.PIPE)
|
|
1669
|
-
self.quit_fun()
|
|
1670
|
-
return True
|
|
1671
|
-
logger.info("Update found but no packages checked for update.")
|
|
1672
1630
|
else:
|
|
1673
1631
|
if show:
|
|
1674
1632
|
msgBox = QtWidgets.QMessageBox()
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
pymodaq/__init__.py,sha256=VtSBaXkrFtgRchmQN2dIet1X88h9r9M6C8OCD9WZPy0,3250
|
|
2
|
-
pymodaq/dashboard.py,sha256=
|
|
2
|
+
pymodaq/dashboard.py,sha256=rUrtOdaK31SKhl1XFagZdvVAEqEwU37WAbplciE6MhE,75119
|
|
3
3
|
pymodaq/icon.ico,sha256=hOHHfNDENKphQvG1WDleSEYcHukneR2eRFJu8isIlD4,74359
|
|
4
4
|
pymodaq/splash.png,sha256=ow8IECF3tPRUMA4tf2tMu1aRiMaxx91_Y2ckVxkrmF0,53114
|
|
5
|
-
pymodaq/updater.py,sha256=JMCVRgAXwmlrKxZv3837E-LRhF0F8V-td_wODwCoXaY,3821
|
|
6
5
|
pymodaq/control_modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
6
|
pymodaq/control_modules/daq_move.py,sha256=emJLJ5t4w-X8L-yo5Jbwg7g_4hP1zPaoq2yGR9S0N5M,38833
|
|
8
7
|
pymodaq/control_modules/daq_move_ui.py,sha256=bdkRX0wjkQuFDr4OT1Q6jT_15DEWV1dn2R6WF50H23s,16811
|
|
@@ -115,8 +114,8 @@ pymodaq/utils/tcp_ip/__init__.py,sha256=1e_EK0AgvdoLAD_CSGGEaITZdy6OWCO7ih9IAIp7
|
|
|
115
114
|
pymodaq/utils/tcp_ip/mysocket.py,sha256=03FaQskso8nLLAsN-ijX-RazXbeMezRnAPvsRxTQa4k,326
|
|
116
115
|
pymodaq/utils/tcp_ip/serializer.py,sha256=Bp6ZpGqMdZlX4CnT371d7ZYqIp7UygsRsE9XFkWZrto,400
|
|
117
116
|
pymodaq/utils/tcp_ip/tcp_server_client.py,sha256=eL-Q1HnnaAG8wfTUb9unEIiNFApMXzfzfveUWoC0_mg,30657
|
|
118
|
-
pymodaq-5.0.
|
|
119
|
-
pymodaq-5.0.
|
|
120
|
-
pymodaq-5.0.
|
|
121
|
-
pymodaq-5.0.
|
|
122
|
-
pymodaq-5.0.
|
|
117
|
+
pymodaq-5.0.14.dist-info/METADATA,sha256=PBseBW0wheA1lpO6ZXPfL42Mhtbg5VCYN4i4SOeDwzo,12894
|
|
118
|
+
pymodaq-5.0.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
119
|
+
pymodaq-5.0.14.dist-info/entry_points.txt,sha256=DvPq6fmIPH2JNsCqHDhn1xEj1kX5tfuc7xQ8-l5S2EU,387
|
|
120
|
+
pymodaq-5.0.14.dist-info/licenses/LICENSE,sha256=VKOejxexXAe3XwfhAhcFGqeXQ12irxVHdeAojZwFEI8,1108
|
|
121
|
+
pymodaq-5.0.14.dist-info/RECORD,,
|
pymodaq/updater.py
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import argparse
|
|
2
|
-
import subprocess
|
|
3
|
-
import sys
|
|
4
|
-
import time
|
|
5
|
-
import logging
|
|
6
|
-
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
|
|
9
|
-
from pymodaq_utils.logger import set_logger, get_module_name
|
|
10
|
-
|
|
11
|
-
logger = set_logger(get_module_name(__file__))
|
|
12
|
-
logger.addHandler(logging.StreamHandler(sys.stdout))
|
|
13
|
-
|
|
14
|
-
def wait_for_parent():
|
|
15
|
-
'''
|
|
16
|
-
A function to wait for its parent to terminate execution.
|
|
17
|
-
|
|
18
|
-
In order to achieve that, this process has to be started with
|
|
19
|
-
stdin replaced by a piped stream from its parent. When the
|
|
20
|
-
parent terminates, stdin will close and either return from read
|
|
21
|
-
or throw an exception. De facto creating a way to wait for its
|
|
22
|
-
parent's termination.
|
|
23
|
-
|
|
24
|
-
It then sleep for 2 seconds, to let the parent process complete
|
|
25
|
-
termination.
|
|
26
|
-
|
|
27
|
-
CAUTION: If the process was not started by piping stdin AND
|
|
28
|
-
the --wait option is set, this function will hang forever.
|
|
29
|
-
|
|
30
|
-
We could use `psutil` or a similar lib to check for parent's process
|
|
31
|
-
existance with its pid.
|
|
32
|
-
'''
|
|
33
|
-
|
|
34
|
-
logger.info("Waiting for parent process to stop.")
|
|
35
|
-
try:
|
|
36
|
-
sys.stdin.read()
|
|
37
|
-
except:
|
|
38
|
-
pass
|
|
39
|
-
logger.debug("Parent process closed stdin")
|
|
40
|
-
time.sleep(2)
|
|
41
|
-
logger.info("Parent process stopped.")
|
|
42
|
-
|
|
43
|
-
def process_args():
|
|
44
|
-
'''
|
|
45
|
-
Declare arguments for updater.py, parse them and returns them in an object.
|
|
46
|
-
The arguments are:
|
|
47
|
-
--file <file> to request a python program to (re)start after update if needed (optional)
|
|
48
|
-
--wait to wait for the starting process to terminate before updating (optional, defaults to False)
|
|
49
|
-
packages the package list to install/update (they should contain the version in a pip accepted format)
|
|
50
|
-
'''
|
|
51
|
-
parser = argparse.ArgumentParser(description='Update pymodaq using pip.')
|
|
52
|
-
parser.add_argument('--file', type=str, help='the pymodaq script to restart after update')
|
|
53
|
-
parser.add_argument("--wait", action="store_true", help="enable waiting for pymodaq to finish mode (default is disabled).")
|
|
54
|
-
parser.add_argument('packages', type=str, nargs='+', help='package list')
|
|
55
|
-
return parser.parse_args()
|
|
56
|
-
|
|
57
|
-
def restart_if_command_launch(args):
|
|
58
|
-
'''
|
|
59
|
-
Try to detect if this process if launched using the declared command (i.e. `pymodaq_updater`)
|
|
60
|
-
or using the script file (`updater.py`). If it uses the command, it restart the process to
|
|
61
|
-
force it to use the script file, thus preventing a locked file during update on windows systems.
|
|
62
|
-
'''
|
|
63
|
-
python_file_path = Path(__file__) # Should be the path to `updater.py`
|
|
64
|
-
started_path = Path(sys.argv[0]) # Either `updater.py` or `pymodaq_updater`
|
|
65
|
-
|
|
66
|
-
# If they're different we'll restart using the script file
|
|
67
|
-
if started_path.absolute() != python_file_path.absolute():
|
|
68
|
-
logger.info("Started as pymodaq_updater, need to restart using python to prevent lock.")
|
|
69
|
-
# We HAVE to wait for this process to stop in the restarted process
|
|
70
|
-
new_args = ['--wait'] + sys.argv[1:]
|
|
71
|
-
if args.wait:
|
|
72
|
-
wait_for_parent()
|
|
73
|
-
|
|
74
|
-
subprocess.Popen([sys.executable, str(python_file_path.absolute())] + new_args, stdin=subprocess.PIPE)
|
|
75
|
-
sys.exit(0)
|
|
76
|
-
|
|
77
|
-
def main():
|
|
78
|
-
args = process_args()
|
|
79
|
-
logger.info(f"Arguments processed: {args}")
|
|
80
|
-
|
|
81
|
-
restart_if_command_launch(args)
|
|
82
|
-
|
|
83
|
-
if args.wait:
|
|
84
|
-
wait_for_parent()
|
|
85
|
-
|
|
86
|
-
packages_str = ', '.join(args.packages)
|
|
87
|
-
logger.info(f'Updating packages: {packages_str}')
|
|
88
|
-
|
|
89
|
-
with subprocess.Popen([sys.executable, '-m', 'pip', 'install'] + args.packages, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pip:
|
|
90
|
-
for line in pip.stdout:
|
|
91
|
-
# Can't decode as some characters are not valid and make the whole process fail
|
|
92
|
-
logger.info(line[:-1])
|
|
93
|
-
ret_code = pip.wait()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if ret_code == 0:
|
|
97
|
-
logger.info(f'Succesfully updated {packages_str}')
|
|
98
|
-
else:
|
|
99
|
-
logger.error(f'Error while updating {packages_str}, pip returned {ret_code}')
|
|
100
|
-
|
|
101
|
-
if args.file is not None:
|
|
102
|
-
logger.info(f"Restarting {args.file} script after update.")
|
|
103
|
-
subprocess.Popen([sys.executable, args.file])
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if __name__ == "__main__":
|
|
107
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|