root/trunk/ftp_path.py

Revision 749, 7.3 kB (checked in by schwa, 3 weeks ago)
Dealt with warnings/errors in production code mentioned by pylint.
  • Property svn:mime-type set to text/x-python
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 # Copyright (C) 2003-2008, Stefan Schwarzer
2 # All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 # - Redistributions of source code must retain the above copyright
9 #   notice, this list of conditions and the following disclaimer.
10 #
11 # - Redistributions in binary form must reproduce the above copyright
12 #   notice, this list of conditions and the following disclaimer in the
13 #   documentation and/or other materials provided with the distribution.
14 #
15 # - Neither the name of the above author nor the names of the
16 #   contributors to the software may be used to endorse or promote
17 #   products derived from this software without specific prior written
18 #   permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
24 # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 """
33 ftp_path.py - simulate `os.path` for FTP servers
34 """
35
36 # $Id$
37
38 import posixpath
39 import stat
40
41 import ftp_error
42
43
44 class _Path(object):
45     """
46     Support class resembling `os.path`, accessible from the `FTPHost`
47     object, e. g. as `FTPHost().path.abspath(path)`.
48
49     Hint: substitute `os` with the `FTPHost` object.
50     """
51
52     def __init__(self, host):
53         self._host = host
54         # delegate these to the `posixpath` module
55         pp = posixpath
56         self.dirname      = pp.dirname
57         self.basename     = pp.basename
58         self.isabs        = pp.isabs
59         self.commonprefix = pp.commonprefix
60         self.join         = pp.join
61         self.split        = pp.split
62         self.splitdrive   = pp.splitdrive
63         self.splitext     = pp.splitext
64         self.normcase     = pp.normcase
65         self.normpath     = pp.normpath
66
67     def abspath(self, path):
68         """Return an absolute path."""
69         if not self.isabs(path):
70             path = self.join(self._host.getcwd(), path)
71         return self.normpath(path)
72
73     def exists(self, path):
74         """Return true if the path exists."""
75         try:
76             lstat_result = self._host.lstat(
77                            path, _exception_for_missing_path=False)
78             return lstat_result is not None
79         except ftp_error.RootDirError:
80             return True
81
82     def getmtime(self, path):
83         """
84         Return the timestamp for the last modification for `path`
85         as a float.
86
87         This will raise `PermanentError` if the path doesn't exist,
88         but maybe other exceptions depending on the state of the
89         server (e. g. timeout).
90         """
91         return self._host.stat(path).st_mtime
92
93     def getsize(self, path):
94         """
95         Return the size of the `path` item as an integer.
96
97         This will raise `PermanentError` if the path doesn't exist,
98         but maybe raise other exceptions depending on the state of the
99         server (e. g. timeout).
100         """
101         return self._host.stat(path).st_size
102
103     # check whether a path is a regular file/dir/link;
104     #  for the first two cases follow links (like in `os.path`)
105     #
106     # Implementation note: The previous implementations simply called
107     # `stat` or `lstat` and returned `False` if they ended with
108     # raising a `PermanentError`. That exception usually used to
109     # signal a missing path. This approach has the problem, however,
110     # that exceptions caused by code earlier in `lstat` are obscured
111     # by the exception handling in `isfile`, `isdir` and `islink`.
112
113     def isfile(self, path):
114         """
115         Return true if the `path` exists and corresponds to a regular
116         file (no link).
117
118         A non-existing path does _not_ cause a `PermanentError`.
119         """
120         # workaround if we can't go up from the current directory
121         if path == self._host.getcwd():
122             return False
123         try:
124             stat_result = self._host.stat(
125                           path, _exception_for_missing_path=False)
126             if stat_result is None:
127                 return False
128             else:
129                 return stat.S_ISREG(stat_result.st_mode)
130         except ftp_error.RootDirError:
131             return False
132
133     def isdir(self, path):
134         """
135         Return true if the `path` exists and corresponds to a
136         directory (no link).
137
138         A non-existing path does _not_ cause a `PermanentError`.
139         """
140         # workaround if we can't go up from the current directory
141         if path == self._host.getcwd():
142             return True
143         try:
144             stat_result = self._host.stat(
145                           path, _exception_for_missing_path=False)
146             if stat_result is None:
147                 return False
148             else:
149                 return stat.S_ISDIR(stat_result.st_mode)
150         except ftp_error.RootDirError:
151             return True
152
153     def islink(self, path):
154         """
155         Return true if the `path` exists and is a link.
156
157         A non-existing path does _not_ cause a `PermanentError`.
158         """
159         try:
160             lstat_result = self._host.lstat(
161                            path, _exception_for_missing_path=False)
162             if lstat_result is None:
163                 return False
164             else:
165                 return stat.S_ISLNK(lstat_result.st_mode)
166         except ftp_error.RootDirError:
167             return False
168
169     def walk(self, top, func, arg):
170         """
171         Directory tree walk with callback function.
172
173         For each directory in the directory tree rooted at top
174         (including top itself, but excluding '.' and '..'), call
175         func(arg, dirname, fnames). dirname is the name of the
176         directory, and fnames a list of the names of the files and
177         subdirectories in dirname (excluding '.' and '..').  func may
178         modify the fnames list in-place (e.g. via del or slice
179         assignment), and walk will only recurse into the
180         subdirectories whose names remain in fnames; this can be used
181         to implement a filter, or to impose a specific order of
182         visiting.  No semantics are defined for, or required of, arg,
183         beyond that arg is always passed to func.  It can be used,
184         e.g., to pass a filename pattern, or a mutable object designed
185         to accumulate statistics.  Passing None for arg is common.
186         """
187         # This code (and the above documentation) is taken from
188         #  posixpath.py, with slight modifications
189         try:
190             names = self._host.listdir(top)
191         except OSError:
192             return
193         func(arg, top, names)
194         for name in names:
195             name = self.join(top, name)
196             try:
197                 stat_result = self._host.lstat(name)
198             except OSError:
199                 continue
200             if stat.S_ISDIR(stat_result[stat.ST_MODE]):
201                 self.walk(name, func, arg)
202
Note: See TracBrowser for help on using the browser.