Package osh :: Package command :: Module ls
[frames] | no frames]

Source Code for Module osh.command.ls

  1  # osh 
  2  # Copyright (C) Jack Orenstein <jao@geophile.com> 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or 
  7  # (at your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, 
 10  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 12  # GNU General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 17   
 18  """C{ls [-01rfds] [FILENAME_PATTERN ...]} 
 19   
 20  Generates a stream of objects of type C{osh.file.File}. Each 
 21  C{FILENAME_PATTERN} is expanded as a Unix "glob" pattern. If no 
 22  C{FILENAME_PATTERN}s are specified, then the files in the current 
 23  directory are output.  If C{-0} (that's a zero) is specified, then 
 24  only files matching the specified C{FILENAME_PATTERN}s are output; any 
 25  qualifying directories are not explored. If C{-1} (that's the digit 
 26  one, not the letter L) is specified, then files are listed and 
 27  directories are expanded to one level.  If C{-r} is specified, then 
 28  directories are recursively explored.  At most one of these flags may 
 29  be specified. If none of these flags are specified, then the behavior 
 30  defaults to C{-1}. 
 31   
 32  If C{-f} is specified, files are listed. If C{-d} is specified, 
 33  directories are listed. If C{-s} is specified, symlinks are listed. 
 34  Combinations of these flags are permitted. If none of these flags are 
 35  specified, then files, directories and symlinks are listed. 
 36   
 37  Symlinks to directories are not explored.""" 
 38   
 39  import os 
 40  import os.path 
 41  import glob 
 42   
 43  import osh.core 
 44  import osh.args 
 45  import osh.file 
 46   
 47  Option = osh.args.Option 
 48  File = osh.file.File 
 49   
 50  # CLI 
51 -def _ls():
52 return _Ls()
53 54 # API
55 -def ls(paths, 56 depth_0 = False, 57 depth_1 = False, 58 recursive = False, 59 file = False, 60 dir = False, 61 link = False):
62 """Generates a stream of objects of type C{osh.file.File}. C{paths} may be a single 63 path or a sequence of paths 64 Each path in C{paths} 65 is expanded as a Unix "glob" pattern. If no path is specified, 66 then the files in the current directory are output. 67 If C{depth_0} is True, then only files matching the specified pathss are 68 output; any qualifying directories are not explored. If C{depth_1} is True, 69 then behavior is as for C{depth_0} except that files in qualifying directories 70 are output as well. If C{recursive} is True, then directories are recursively explored. 71 At most one of the last three arguments may be True. If all are False, 72 then C{depth_1} behavior is obtained. Files are listed if and only if C{file} is 73 true. Directories are listed if and only if C{dir} is true. Symlinks are listed 74 if and only if C{link} is true. If C{file}, C{dir} and C{link} are all false, 75 then files, directories and symlinks are listed. Symlinks to directories are 76 not explored. 77 """ 78 args = [] 79 if depth_0: 80 args.append(Option('-0')) 81 if depth_1: 82 args.append(Option('-1')) 83 if recursive: 84 args.append(Option('-r')) 85 if file: 86 args.append(Option('-f')) 87 if dir: 88 args.append(Option('-d')) 89 if link: 90 args.append(Option('-s')) 91 if isinstance(paths, str): 92 paths = [paths] 93 args.extend(paths) 94 return _Ls().process_args(*args)
95
96 -class _Ls(osh.core.Generator):
97 98 _recursion = None 99 _patterns = None 100 _lister = None 101 _list_file = None 102 _list_dir = None 103 _list_link = None 104 105 # object interface 106
107 - def __init__(self):
108 osh.core.Generator.__init__(self, '01rfds', (0, None))
109 110 # BaseOp interface 111
112 - def doc(self):
113 return __doc__
114
115 - def setup(self):
116 args = self.args() 117 depth0 = args.flag('-0') 118 depth1 = args.flag('-1') 119 recursive = args.flag('-r') 120 count = 0 121 if depth0: 122 count += 1 123 self._lister = _Lister0(self) 124 if depth1: 125 count += 1 126 self._lister = _Lister1(self) 127 if recursive: 128 count += 1 129 self._lister = _ListerRecursive(self) 130 if count == 0: 131 self._lister = _Lister1(self) 132 elif count > 1: 133 self.usage() 134 self._list_file = args.flag('-f') 135 self._list_dir = args.flag('-d') 136 self._list_link = args.flag('-s') 137 if not (self._list_file or self._list_dir or self._list_link): 138 self._list_file = True 139 self._list_dir = True 140 self._list_link = True 141 self._patterns = args.remaining() 142 if len(self._patterns) == 0: 143 self._patterns = ['.']
144 145 # Generator interface 146
147 - def execute(self):
148 for pattern in self._patterns: 149 for path in glob.glob(pattern): 150 file = File(path) 151 self._lister.list(path)
152
153 -class _Lister(object):
154
155 - def __init__(self, ls):
156 self._ls = ls
157
158 - def send(self, file):
159 ls = self._ls 160 if (file.isfile and ls._list_file or 161 file.isdir and ls._list_dir or 162 file.islink and ls._list_link): 163 ls.send(file)
164
165 -class _Lister0(_Lister):
166
167 - def __init__(self, ls):
168 _Lister.__init__(self, ls)
169
170 - def list(self, path):
171 self.send(File(path))
172
173 -class _Lister1(_Lister):
174
175 - def __init__(self, ls):
176 _Lister.__init__(self, ls)
177
178 - def list(self, path):
179 file = File(path) 180 self.send(file) 181 if file.isdir: 182 for filename in os.listdir(path): 183 file = File(path, filename) 184 self.send(file)
185
186 -class _ListerRecursive(_Lister):
187
188 - def __init__(self, ls):
189 _Lister.__init__(self, ls)
190
191 - def list(self, path):
192 def visit(lister, dirname, filenames): 193 dir = File(dirname) 194 lister.send(dir) 195 if dir.islink: 196 # Prevent exloring link 197 del filenames[:] 198 else: 199 for filename in filenames: 200 file = File(dirname, filename) 201 if not file.isdir: 202 lister.send(file)
203 # else: Will be send when the subdir is visited. 204 if os.path.isdir(path) and not os.path.islink(path): 205 os.path.walk(path, visit, self) 206 else: 207 self.send(File(path))
208