Mon, 06 Feb 2023 15:02:57 +0100
Added a CircuitPython menu entry to show the installed and available firmware version.
--- a/src/eric7/APIs/Python3/eric7.api Mon Feb 06 11:00:29 2023 +0100 +++ b/src/eric7/APIs/Python3/eric7.api Mon Feb 06 15:02:57 2023 +0100 @@ -2540,6 +2540,7 @@ eric7.MicroPython.AddEditDevicesDialog.AddEditDevicesDialog?1(vid=0, pid=0, description=0, deviceData=None, parent=None) eric7.MicroPython.BoardDataDialog.BoardDataDialog?1(data, parent=None) eric7.MicroPython.CircuitPythonDevices.CircuitPythonDevice.DeviceVolumeName?7 +eric7.MicroPython.CircuitPythonDevices.CircuitPythonDevice.GitHubFirmwareUrl?7 eric7.MicroPython.CircuitPythonDevices.CircuitPythonDevice.addDeviceMenuEntries?4(menu) eric7.MicroPython.CircuitPythonDevices.CircuitPythonDevice.canRunScript?4() eric7.MicroPython.CircuitPythonDevices.CircuitPythonDevice.canStartFileManager?4()
--- a/src/eric7/Documentation/Help/source.qhp Mon Feb 06 11:00:29 2023 +0100 +++ b/src/eric7/Documentation/Help/source.qhp Mon Feb 06 15:02:57 2023 +0100 @@ -2694,12 +2694,14 @@ <keyword name="CircuitPythonDevice" id="CircuitPythonDevice" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice" /> <keyword name="CircuitPythonDevice (Constructor)" id="CircuitPythonDevice (Constructor)" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__init__" /> <keyword name="CircuitPythonDevice.__aboutToShowLibraryMenu" id="CircuitPythonDevice.__aboutToShowLibraryMenu" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__aboutToShowLibraryMenu" /> + <keyword name="CircuitPythonDevice.__cpyVersionResponse" id="CircuitPythonDevice.__cpyVersionResponse" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__cpyVersionResponse" /> <keyword name="CircuitPythonDevice.__deviceVolumeMounted" id="CircuitPythonDevice.__deviceVolumeMounted" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__deviceVolumeMounted" /> <keyword name="CircuitPythonDevice.__findDeviceDirectories" id="CircuitPythonDevice.__findDeviceDirectories" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__findDeviceDirectories" /> <keyword name="CircuitPythonDevice.__findWorkspace" id="CircuitPythonDevice.__findWorkspace" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__findWorkspace" /> <keyword name="CircuitPythonDevice.__flashCircuitPython" id="CircuitPythonDevice.__flashCircuitPython" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__flashCircuitPython" /> <keyword name="CircuitPythonDevice.__flashTeensy" id="CircuitPythonDevice.__flashTeensy" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__flashTeensy" /> <keyword name="CircuitPythonDevice.__installLibraryFiles" id="CircuitPythonDevice.__installLibraryFiles" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__installLibraryFiles" /> + <keyword name="CircuitPythonDevice.__showCircuitPythonVersions" id="CircuitPythonDevice.__showCircuitPythonVersions" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.__showCircuitPythonVersions" /> <keyword name="CircuitPythonDevice.addDeviceMenuEntries" id="CircuitPythonDevice.addDeviceMenuEntries" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.addDeviceMenuEntries" /> <keyword name="CircuitPythonDevice.canRunScript" id="CircuitPythonDevice.canRunScript" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.canRunScript" /> <keyword name="CircuitPythonDevice.canStartFileManager" id="CircuitPythonDevice.canStartFileManager" ref="eric7.MicroPython.CircuitPythonDevices.html#CircuitPythonDevice.canStartFileManager" />
--- a/src/eric7/Documentation/Source/eric7.MicroPython.CircuitPythonDevices.html Mon Feb 06 11:00:29 2023 +0100 +++ b/src/eric7/Documentation/Source/eric7.MicroPython.CircuitPythonDevices.html Mon Feb 06 15:02:57 2023 +0100 @@ -47,7 +47,7 @@ <h3>Class Attributes</h3> <table> -<tr><td>DeviceVolumeName</td></tr> +<tr><td>DeviceVolumeName</td></tr><tr><td>GitHubFirmwareUrl</td></tr> </table> <h3>Class Methods</h3> @@ -67,6 +67,10 @@ <td>Private slot to populate the 'Library Management' menu.</td> </tr> <tr> +<td><a href="#CircuitPythonDevice.__cpyVersionResponse">__cpyVersionResponse</a></td> +<td>Private method handling the response of the latest version request.</td> +</tr> +<tr> <td><a href="#CircuitPythonDevice.__deviceVolumeMounted">__deviceVolumeMounted</a></td> <td>Private method to check, if the device volume is mounted.</td> </tr> @@ -91,6 +95,10 @@ <td>Private slot to install Python files into the onboard library.</td> </tr> <tr> +<td><a href="#CircuitPythonDevice.__showCircuitPythonVersions">__showCircuitPythonVersions</a></td> +<td>Private slot to show the CircuitPython version of a connected device and the latest available one (from Github).</td> +</tr> +<tr> <td><a href="#CircuitPythonDevice.addDeviceMenuEntries">addDeviceMenuEntries</a></td> <td>Public method to add device specific entries to the given menu.</td> </tr> @@ -186,6 +194,20 @@ <p> Private slot to populate the 'Library Management' menu. </p> +<a NAME="CircuitPythonDevice.__cpyVersionResponse" ID="CircuitPythonDevice.__cpyVersionResponse"></a> +<h4>CircuitPythonDevice.__cpyVersionResponse</h4> +<b>__cpyVersionResponse</b>(<i>reply</i>) + +<p> + Private method handling the response of the latest version request. +</p> +<dl> + +<dt><i>reply</i> (QNetworkReply)</dt> +<dd> +reference to the reply object +</dd> +</dl> <a NAME="CircuitPythonDevice.__deviceVolumeMounted" ID="CircuitPythonDevice.__deviceVolumeMounted"></a> <h4>CircuitPythonDevice.__deviceVolumeMounted</h4> <b>__deviceVolumeMounted</b>(<i></i>) @@ -288,6 +310,14 @@ (defaults to False) </dd> </dl> +<a NAME="CircuitPythonDevice.__showCircuitPythonVersions" ID="CircuitPythonDevice.__showCircuitPythonVersions"></a> +<h4>CircuitPythonDevice.__showCircuitPythonVersions</h4> +<b>__showCircuitPythonVersions</b>(<i></i>) + +<p> + Private slot to show the CircuitPython version of a connected device and + the latest available one (from Github). +</p> <a NAME="CircuitPythonDevice.addDeviceMenuEntries" ID="CircuitPythonDevice.addDeviceMenuEntries"></a> <h4>CircuitPythonDevice.addDeviceMenuEntries</h4> <b>addDeviceMenuEntries</b>(<i>menu</i>)
--- a/src/eric7/MicroPython/CircuitPythonDevices.py Mon Feb 06 11:00:29 2023 +0100 +++ b/src/eric7/MicroPython/CircuitPythonDevices.py Mon Feb 06 15:02:57 2023 +0100 @@ -10,11 +10,13 @@ import os import shutil -from PyQt6.QtCore import pyqtSlot +from PyQt6.QtCore import QUrl, pyqtSlot +from PyQt6.QtNetwork import QNetworkRequest from PyQt6.QtWidgets import QMenu -from eric7 import Preferences +from eric7 import Globals, Preferences from eric7.EricWidgets import EricFileDialog, EricMessageBox +from eric7.EricWidgets.EricApplication import ericApp from eric7.SystemUtilities import FileSystemUtilities from .CircuitPythonUpdater.CircuitPythonUpdaterInterface import ( @@ -31,6 +33,7 @@ """ DeviceVolumeName = "CIRCUITPY" + GitHubFirmwareUrl = "https://github.com/adafruit/circuitpython/releases/latest" def __init__(self, microPythonWidget, deviceType, boardName, parent=None): """ @@ -252,6 +255,9 @@ self.__libraryMenu.setTearOffEnabled(True) act = menu.addAction( + self.tr("Show CircuitPython Versions"), self.__showCircuitPythonVersions + ) + act = menu.addAction( self.tr("Flash CircuitPython Firmware"), self.__flashCircuitPython ) act.setEnabled(not connected) @@ -328,6 +334,54 @@ ) @pyqtSlot() + def __showCircuitPythonVersions(self): + """ + Private slot to show the CircuitPython version of a connected device and + the latest available one (from Github). + """ + ui = ericApp().getObject("UserInterface") + request = QNetworkRequest(QUrl(CircuitPythonDevice.GitHubFirmwareUrl)) + reply = ui.networkAccessManager().head(request) + reply.finished.connect(lambda: self.__cpyVersionResponse(reply)) + + def __cpyVersionResponse(self, reply): + """ + Private method handling the response of the latest version request. + + @param reply reference to the reply object + @type QNetworkReply + """ + latestUrl = reply.url().toString() + tag = latestUrl.rsplit("/", 1)[-1] + latestVersion = Globals.versionToTuple(tag) + + cpyVersionStr = self.tr("unknown") + cpyVersion = (0, 0, 0) + if self.supportsLocalFileAccess(): + bootFile = os.path.join(self.getWorkspace(), "boot_out.txt") + if os.path.exists(bootFile): + with open(bootFile, "r") as f: + line = f.readline() + cpyVersionStr = line.split(";")[0].split()[2] + cpyVersion = Globals.versionToTuple(cpyVersionStr) + + msg = self.tr( + "<h4>CircuitPython Version Information</h4>" + "<table>" + "<tr><td>Installed:</td><td>{0}</td></tr>" + "<tr><td>Available:</td><td>{1}</td></tr>" + "</table>" + ).format(cpyVersionStr, tag) + if cpyVersion < latestVersion and self.supportsLocalFileAccess(): + msg += self.tr("<p><b>Update available!</b></p>") + + EricMessageBox.information( + None, + self.tr("CircuitPython Version"), + msg, + ) + + @pyqtSlot() def __installLibraryFiles(self, packageMode=False): """ Private slot to install Python files into the onboard library.