8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 import shutil |
11 import shutil |
12 |
12 |
13 from PyQt6.QtCore import pyqtSlot |
13 from PyQt6.QtCore import QUrl, pyqtSlot |
|
14 from PyQt6.QtNetwork import QNetworkRequest |
14 from PyQt6.QtWidgets import QMenu |
15 from PyQt6.QtWidgets import QMenu |
15 |
16 |
16 from eric7 import Preferences |
17 from eric7 import Globals, Preferences |
17 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
18 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
|
19 from eric7.EricWidgets.EricApplication import ericApp |
18 from eric7.SystemUtilities import FileSystemUtilities |
20 from eric7.SystemUtilities import FileSystemUtilities |
19 |
21 |
20 from .CircuitPythonUpdater.CircuitPythonUpdaterInterface import ( |
22 from .CircuitPythonUpdater.CircuitPythonUpdaterInterface import ( |
21 CircuitPythonUpdaterInterface, |
23 CircuitPythonUpdaterInterface, |
22 isCircupAvailable, |
24 isCircupAvailable, |
29 """ |
31 """ |
30 Class implementing the device for CircuitPython boards. |
32 Class implementing the device for CircuitPython boards. |
31 """ |
33 """ |
32 |
34 |
33 DeviceVolumeName = "CIRCUITPY" |
35 DeviceVolumeName = "CIRCUITPY" |
|
36 GitHubFirmwareUrl = "https://github.com/adafruit/circuitpython/releases/latest" |
34 |
37 |
35 def __init__(self, microPythonWidget, deviceType, boardName, parent=None): |
38 def __init__(self, microPythonWidget, deviceType, boardName, parent=None): |
36 """ |
39 """ |
37 Constructor |
40 Constructor |
38 |
41 |
250 self.__libraryMenu = QMenu(self.tr("Library Management")) |
253 self.__libraryMenu = QMenu(self.tr("Library Management")) |
251 self.__libraryMenu.aboutToShow.connect(self.__aboutToShowLibraryMenu) |
254 self.__libraryMenu.aboutToShow.connect(self.__aboutToShowLibraryMenu) |
252 self.__libraryMenu.setTearOffEnabled(True) |
255 self.__libraryMenu.setTearOffEnabled(True) |
253 |
256 |
254 act = menu.addAction( |
257 act = menu.addAction( |
|
258 self.tr("Show CircuitPython Versions"), self.__showCircuitPythonVersions |
|
259 ) |
|
260 act = menu.addAction( |
255 self.tr("Flash CircuitPython Firmware"), self.__flashCircuitPython |
261 self.tr("Flash CircuitPython Firmware"), self.__flashCircuitPython |
256 ) |
262 ) |
257 act.setEnabled(not connected) |
263 act.setEnabled(not connected) |
258 menu.addSeparator() |
264 menu.addSeparator() |
259 menu.addMenu(self.__libraryMenu) |
265 menu.addMenu(self.__libraryMenu) |
323 """ application to flash CircuitPython. Make sure you""" |
329 """ application to flash CircuitPython. Make sure you""" |
324 """ downloaded the CircuitPython .hex file.</p>""" |
330 """ downloaded the CircuitPython .hex file.</p>""" |
325 """<p>See <a href="{0}">the PJRC Teensy web site</a>""" |
331 """<p>See <a href="{0}">the PJRC Teensy web site</a>""" |
326 """ for details.</p>""" |
332 """ for details.</p>""" |
327 ).format("https://www.pjrc.com/teensy/loader.html"), |
333 ).format("https://www.pjrc.com/teensy/loader.html"), |
|
334 ) |
|
335 |
|
336 @pyqtSlot() |
|
337 def __showCircuitPythonVersions(self): |
|
338 """ |
|
339 Private slot to show the CircuitPython version of a connected device and |
|
340 the latest available one (from Github). |
|
341 """ |
|
342 ui = ericApp().getObject("UserInterface") |
|
343 request = QNetworkRequest(QUrl(CircuitPythonDevice.GitHubFirmwareUrl)) |
|
344 reply = ui.networkAccessManager().head(request) |
|
345 reply.finished.connect(lambda: self.__cpyVersionResponse(reply)) |
|
346 |
|
347 def __cpyVersionResponse(self, reply): |
|
348 """ |
|
349 Private method handling the response of the latest version request. |
|
350 |
|
351 @param reply reference to the reply object |
|
352 @type QNetworkReply |
|
353 """ |
|
354 latestUrl = reply.url().toString() |
|
355 tag = latestUrl.rsplit("/", 1)[-1] |
|
356 latestVersion = Globals.versionToTuple(tag) |
|
357 |
|
358 cpyVersionStr = self.tr("unknown") |
|
359 cpyVersion = (0, 0, 0) |
|
360 if self.supportsLocalFileAccess(): |
|
361 bootFile = os.path.join(self.getWorkspace(), "boot_out.txt") |
|
362 if os.path.exists(bootFile): |
|
363 with open(bootFile, "r") as f: |
|
364 line = f.readline() |
|
365 cpyVersionStr = line.split(";")[0].split()[2] |
|
366 cpyVersion = Globals.versionToTuple(cpyVersionStr) |
|
367 |
|
368 msg = self.tr( |
|
369 "<h4>CircuitPython Version Information</h4>" |
|
370 "<table>" |
|
371 "<tr><td>Installed:</td><td>{0}</td></tr>" |
|
372 "<tr><td>Available:</td><td>{1}</td></tr>" |
|
373 "</table>" |
|
374 ).format(cpyVersionStr, tag) |
|
375 if cpyVersion < latestVersion and self.supportsLocalFileAccess(): |
|
376 msg += self.tr("<p><b>Update available!</b></p>") |
|
377 |
|
378 EricMessageBox.information( |
|
379 None, |
|
380 self.tr("CircuitPython Version"), |
|
381 msg, |
328 ) |
382 ) |
329 |
383 |
330 @pyqtSlot() |
384 @pyqtSlot() |
331 def __installLibraryFiles(self, packageMode=False): |
385 def __installLibraryFiles(self, packageMode=False): |
332 """ |
386 """ |