eric6/MicroPython/MicroPythonFileSystem.py

branch
micropython
changeset 7082
ec199ef0cfc6
parent 7081
ed510767c096
child 7083
217862c28319
diff -r ed510767c096 -r ec199ef0cfc6 eric6/MicroPython/MicroPythonFileSystem.py
--- a/eric6/MicroPython/MicroPythonFileSystem.py	Tue Jul 23 19:43:14 2019 +0200
+++ b/eric6/MicroPython/MicroPythonFileSystem.py	Wed Jul 24 20:12:19 2019 +0200
@@ -74,10 +74,13 @@
         """
         Private method to switch the connected device to 'raw' mode.
         
-        Note: switching to raw mode is done with synchroneous writes.
+        Note: switching to raw mode is done with synchronous writes.
+        
+        @return flag indicating success
+        @@rtype bool
         """
         if not self.__serial:
-            return
+            return False
         
         rawReplMessage = b"raw REPL; CTRL-B to exit\r\n"
         softRebootMessage = b"soft reboot\r\n"
@@ -92,16 +95,25 @@
         self.__serial.readAll()             # read all data and discard it
         self.__serial.write(b"\r\x01")      # send CTRL-A to enter raw mode
         self.__serial.readUntil(rawReplMessage)
+        if self.__serial.hasTimedOut():
+            return False
         self.__serial.write(b"\x04")        # send CTRL-D to soft reset
         self.__serial.readUntil(softRebootMessage)
+        if self.__serial.hasTimedOut():
+            return False
         
         # some MicroPython devices seem to need to be convinced in some
         # special way
         data = self.__serial.readUntil(rawReplMessage)
+        if self.__serial.hasTimedOut():
+            return False
         if not data.endswith(rawReplMessage):
             self.__serial.write(b"\r\x01")  # send CTRL-A again
             self.__serial.readUntil(rawReplMessage)
+            if self.__serial.hasTimedOut():
+                return False
         self.__serial.readAll()             # read all data and discard it
+        return True
     
     def __rawOff(self):
         """
@@ -128,7 +140,13 @@
         result = bytearray()
         err = b""
         
-        self.__rawOn()
+        ok = self.__rawOn()
+        if not ok:
+            return (
+                b"",
+                b"Could not switch to raw mode. Is the device switched on?"
+            )
+        
         QThread.msleep(10)
         for command in commands:
             if command:
@@ -136,9 +154,14 @@
                 self.__serial.write(commandBytes + b"\x04")
                 # read until prompt
                 response = self.__serial.readUntil(b"\x04>")
-                # split stdout, stderr
-                out, err = response[2:-2].split(b"\x04")
-                result += out
+                if self.__serial.hasTimedOut():
+                    return b"", b"Timeout while processing commands."
+                if b"\x04" in response[2:-2]:
+                    # split stdout, stderr
+                    out, err = response[2:-2].split(b"\x04")
+                    result += out
+                else:
+                    err = b"invalid response received: " + response
                 if err:
                     return b"", err
         QThread.msleep(10)
@@ -511,21 +534,30 @@
                 "    try:",           # Pyboard (it doesn't have machine.RTC())
                 "        import pyb",
                 "        rtc = pyb.RTC()",
-                "        rtc.datetime(rtc_time)",
+                "        clock_time = rtc_time[:6] + (rtc_time[6] + 1, 0)",
+                "        rtc.datetime(clock_time)",
                 "    except:",
                 "        try:",
                 "            import machine",
                 "            rtc = machine.RTC()",
-                "            try:",     # ESP8266 uses rtc.datetime()
-                "                rtc.datetime(rtc_time)",
+                "            try:",     # ESP8266 may use rtc.datetime()
+                "                clock_time = rtc_time[:6] +"
+                " (rtc_time[6] + 1, 0)",
+                "                rtc.datetime(clock_time)",
                 "            except:",  # ESP32 uses rtc.init()
-                "                rtc.init(rtc_time)",
+                "                rtc.init(rtc_time[:6])",
                 "        except:",
-                "            pass",
+                "            try:",
+                "                import rtc, time",
+                "                clock=rtc.RTC()",
+                "                clock.datetime = time.struct_time(rtc_time +"
+                " (-1, -1))",
+                "            except:",
+                "                pass",
             ]),
             "set_time({0})".format((now.tm_year, now.tm_mon, now.tm_mday,
-                                    now.tm_wday + 1, now.tm_hour, now.tm_min,
-                                    now.tm_sec, 0))
+                                    now.tm_hour, now.tm_min, now.tm_sec,
+                                    now.tm_wday))
         ]
         out, err = self.__execute(commands)
         if err:
@@ -570,21 +602,17 @@
     @signal rsyncDone(localName, deviceName) emitted after the rsync operation
         has been completed
     @signal rsyncMessages(list) emitted with a list of messages
+    @signal removeDirectoryDone() emitted after a directory has been deleted
+    @signal createDirectoryDone() emitted after a directory was created
+    @signal synchTimeDone() emitted after the time was synchronizde to the
+        device
+    @signal showTimeDone(dateTime) emitted after the date and time was fetched
+        from the connected device
+    @signal showVersionDone(versionInfo) emitted after the version information
+        was fetched from the connected device
     
-    @signal longListFilesFailed(exc) emitted with a failure message to indicate
-        a failed long listing operation
-    @signal currentDirFailed(exc) emitted with a failure message to indicate
-        that the current directory is not available
-    @signal currentDirChangeFailed(exc) emitted with a failure message to
-        indicate that the current directory could not be changed
-    @signal getFileFailed(exc) emitted with a failure message to indicate that
-        the file could not be fetched
-    @signal putFileFailed(exc) emitted with a failure message to indicate that
-        the file could not be copied
-    @signal deleteFileFailed(exc) emitted with a failure message to indicate
-        that the file could not be deleted on the device
-    @signal rsyncFailed(exc) emitted with a failure message to indicate that
-        the rsync operation could not be completed
+    @signal error(exc) emitted with a failure message to indicate a failure
+        during the most recent operation
     """
     longListFiles = pyqtSignal(tuple)
     currentDir = pyqtSignal(str)
@@ -594,14 +622,13 @@
     deleteFileDone = pyqtSignal(str)
     rsyncDone = pyqtSignal(str, str)
     rsyncMessages = pyqtSignal(list)
+    removeDirectoryDone = pyqtSignal()
+    createDirectoryDone = pyqtSignal()
+    synchTimeDone = pyqtSignal()
+    showTimeDone = pyqtSignal(str)
+    showVersionDone = pyqtSignal(dict)
     
-    longListFilesFailed = pyqtSignal(str)
-    currentDirFailed = pyqtSignal(str)
-    currentDirChangeFailed = pyqtSignal(str)
-    getFileFailed = pyqtSignal(str)
-    putFileFailed = pyqtSignal(str)
-    deleteFileFailed = pyqtSignal(str)
-    rsyncFailed = pyqtSignal(str)
+    error = pyqtSignal(str, str)
     
     def __init__(self, port, parent=None):
         """
@@ -650,7 +677,7 @@
                       name, (mode, size, time) in filesList]
             self.longListFiles.emit(tuple(result))
         except Exception as exc:
-            self.longListFilesFailed.emit(str(exc))
+            self.error.emit("lls", str(exc))
     
     @pyqtSlot()
     def pwd(self):
@@ -661,7 +688,7 @@
             pwd = self.__fs.pwd()
             self.currentDir.emit(pwd)
         except Exception as exc:
-            self.currentDirFailed.emit(str(exc))
+            self.error.emit("pwd", str(exc))
     
     @pyqtSlot(str)
     def cd(self, dirname):
@@ -675,7 +702,7 @@
             self.__fs.cd(dirname)
             self.currentDirChanged.emit(dirname)
         except Exception as exc:
-            self.currentDirChangeFailed.emit(str(exc))
+            self.error.emit("cd", str(exc))
     
     @pyqtSlot(str)
     @pyqtSlot(str, str)
@@ -696,7 +723,7 @@
             self.__fs.get(deviceFileName, hostFileName)
             self.getFileDone.emit(deviceFileName, hostFileName)
         except Exception as exc:
-            self.getFileFailed.emit(str(exc))
+            self.error.emit("get", str(exc))
     
     @pyqtSlot(str)
     @pyqtSlot(str, str)
@@ -713,7 +740,7 @@
             self.__fs.put(hostFileName, deviceFileName)
             self.putFileDone.emit(hostFileName, deviceFileName)
         except Exception as exc:
-            self.putFileFailed.emit(str(exc))
+            self.error.emit("put", str(exc))
     
     @pyqtSlot(str)
     def delete(self, deviceFileName):
@@ -727,7 +754,7 @@
             self.__fs.rm(deviceFileName)
             self.deleteFileDone.emit(deviceFileName)
         except Exception as exc:
-            self.deleteFileFailed.emit(str(exc))
+            self.error.emit("delete", str(exc))
     
     def __rsync(self, hostDirectory, deviceDirectory, mirror=True):
         """
@@ -841,9 +868,11 @@
         
         return messages, errors
     
+    @pyqtSlot(str, str)
+    @pyqtSlot(str, str, bool)
     def rsync(self, hostDirectory, deviceDirectory, mirror=True):
         """
-        Public method to synchronize a local directory to the device.
+        Public slot to synchronize a local directory to the device.
         
         @param hostDirectory name of the local directory
         @type str
@@ -856,9 +885,82 @@
         messages, errors = self.__rsync(hostDirectory, deviceDirectory,
                                         mirror=mirror)
         if errors:
-            self.rsyncFailed.emit("\n".join(errors))
+            self.error.emit("rsync", "\n".join(errors))
         
         if messages:
             self.rsyncMessages.emit(messages)
         
         self.rsyncDone.emit(hostDirectory, deviceDirectory)
+    
+    @pyqtSlot(str)
+    def mkdir(self, dirname):
+        """
+        Public slot to create a new directory.
+        
+        @param dirname name of the directory to create
+        @type str
+        """
+        try:
+            self.__fs.mkdir(dirname)
+            self.createDirectoryDone.emit()
+        except Exception as exc:
+            self.error.emit("mkdir", str(exc))
+    
+    @pyqtSlot(str)
+    @pyqtSlot(str, bool)
+    def rmdir(self, dirname, recursive=False):
+        """
+        Public slot to (recursively) remove a directory.
+        
+        @param dirname name of the directory to be removed
+        @type str
+        @param recursive flag indicating a recursive removal
+        @type bool
+        """
+        try:
+            if recursive:
+                self.__fs.rmrf(dirname, recursive=True, force=True)
+            else:
+                self.__fs.rmdir(dirname)
+            self.removeDirectoryDone.emit()
+        except Exception as exc:
+            self.error.emit("rmdir", str(exc))
+    
+    ##################################################################
+    ## some non-filesystem related methods below
+    ##################################################################
+    
+    @pyqtSlot()
+    def synchronizeTime(self):
+        """
+        Public slot to set the time of the connected device to the local
+        computer's time.
+        """
+        try:
+            self.__fs.syncTime()
+            self.synchTimeDone.emit()
+        except Exception as exc:
+            self.error.emit("rmdir", str(exc))
+    
+    @pyqtSlot()
+    def showTime(self):
+        """
+        Public slot to get the current date and time of the device.
+        """
+        try:
+            dt = self.__fs.showTime()
+            self.showTimeDone.emit(dt)
+        except Exception as exc:
+            self.error.emit("showTime", str(exc))
+    
+    @pyqtSlot()
+    def showVersion(self):
+        """
+        Public slot to get the version info for the MicroPython run by the
+        connected device.
+        """
+        try:
+            versionInfo = self.__fs.version()
+            self.showVersionDone.emit(versionInfo)
+        except Exception as exc:
+            self.error.emit("showVersion", str(exc))

eric ide

mercurial