src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py

branch
server
changeset 10583
2114cc7275e8
parent 10577
b9edebd77c91
child 10584
a596cf392291
--- a/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py	Sat Feb 17 11:26:37 2024 +0100
+++ b/src/eric7/RemoteServerInterface/EricServerFileSystemInterface.py	Sat Feb 17 19:46:33 2024 +0100
@@ -9,6 +9,9 @@
 
 import base64
 import contextlib
+import fnmatch
+import os
+import re
 import stat
 
 from PyQt6.QtCore import QEventLoop, QObject
@@ -17,12 +20,13 @@
 from eric7.SystemUtilities import FileSystemUtilities
 
 
-# TODO: sanitize all file names with FileSystemUtilities.plainFileName()
 class EricServerFileSystemInterface(QObject):
     """
     Class implementing the file system interface to the eric-ide server.
     """
 
+    _MagicCheck = re.compile("([*?[])")
+
     def __init__(self, serverInterface):
         """
         Constructor
@@ -34,6 +38,20 @@
 
         self.__serverInterface = serverInterface
 
+    def __hasMagic(self, pathname):
+        """
+        Private method to check, if a given path contains glob style magic characters.
+
+        Note: This was taken from 'glob.glob'.
+
+        @param pathname path name to be checked
+        @type str
+        @return flag indicating the presence of magic characters
+        @rtype bool
+        """
+        match = self._MagicCheck.search(pathname)
+        return match is not None
+
     def getcwd(self):
         """
         Public method to get the current working directory of the eric-ide server.
@@ -175,7 +193,14 @@
         return listedDirectory, separator, listing
 
     def direntries(
-        self, directory, filesonly=False, pattern=None, followsymlinks=True, ignore=None
+        self,
+        directory,
+        filesonly=False,
+        pattern=None,
+        followsymlinks=True,
+        ignore=None,
+        recursive=True,
+        dirsonly=False,
     ):
         """
         Public method to get a list of all files and directories of a given directory.
@@ -192,6 +217,11 @@
         @type bool (optional)
         @param ignore list of entries to be ignored (defaults to None)
         @type list of str (optional)
+        @param recursive flag indicating a recursive search (defaults to True)
+        @type bool (optional)
+        @param dirsonly flag indicating to return only directories. When True it has
+            precedence over the 'filesonly' parameter ((defaults to False)
+        @type bool
         @return list of all files and directories in the tree rooted at path.
             The names are expanded to start with the given directory name.
         @rtype list of str
@@ -231,6 +261,8 @@
                     "pattern": [] if pattern is None else pattern,
                     "follow_symlinks": followsymlinks,
                     "ignore": [] if ignore is None else ignore,
+                    "recursive": recursive,
+                    "dirs_only": dirsonly,
                 },
                 callback=callback,
             )
@@ -241,6 +273,36 @@
 
         return result
 
+    def glob(self, pathname, recursive=False, includeHidden=False):
+        """
+        Public method to get a list of of all files matching a given pattern
+        like 'glob.glob()'.
+
+        @param pathname path name pattern with simple shell-style wildcards
+        @type str
+        @param recursive flag indicating a recursive list (defaults to False)
+        @type bool (optional)
+        @param includeHidden flag indicating to include hidden files (defaults to False)
+        @type bool (optional)
+        @return list of all files matching the pattern
+        @rtype list of str
+        """
+        result = []
+
+        pathname = FileSystemUtilities.plainFileName(pathname)
+        dirname, basename = os.path.split(pathname)
+        if dirname and not self.__hasMagic(dirname):
+            with contextlib.suppress(OSError):
+                entries = self.direntries(
+                    dirname, pattern=basename, recursive=recursive, filesonly=True
+                )
+                if includeHidden:
+                    result = entries
+                else:
+                    result = [e for e in entries if not e.startswith(".")]
+
+        return result
+
     def stat(self, filename, stNames):
         """
         Public method to get the status of a file.

eric ide

mercurial