/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Lib/fileutil.py
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/Thuban/Lib/fileutil.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Tue Aug 28 15:41:52 2001 UTC (23 years, 6 months ago) by bh
Original Path: trunk/thuban/Thuban/Lib/fileutil.py
File MIME type: text/x-python
File size: 6412 byte(s)
import all the source files

1 # Copyright (c) 2001 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 #
5 # This program is free software under the GPL (>=v2)
6 # Read the file COPYING coming with Thuban for details.
7
8 """
9 Functions to deal with filenames
10 """
11
12 __version__ = "$Revision$"
13
14 import os.path
15 from string import split, join
16
17
18 def relative_filename_common(dir, absname, sep):
19 """Return a filename relative to dir for the absolute file name absname.
20 This is part the posix and nt versions have in common. Both dir and
21 absname are assumed to be normalized (as done with os.normpath)
22 absolute filenames without drive letters. sep is the platform
23 specific directory separator.
24 """
25
26 # split the filenames into their components. remove the first item
27 # since it will be always empty because both names are absolute.
28 dir_parts = split(dir, sep)[1:]
29 absname_parts = split(absname, sep)[1:]
30
31 # count the number of common parts at the start of dir_parts and
32 # absname_parts
33 max_common = min(len(dir_parts), len(absname_parts))
34 common = 0
35 while common < max_common and dir_parts[common] == absname_parts[common]:
36 common = common + 1
37
38 # If the common part is the root directory, return absname
39 if common == 0:
40 return absname
41
42 # for each directory under the common part prepend a '..'.
43 rel_parts = (len(dir_parts) - common) * ['..'] + absname_parts[common:]
44 return join(rel_parts, sep)
45
46
47 def relative_filename_posix(dir, absname):
48 """Return a filename relative to dir for the absolute file name absname.
49
50 If absname is already a relative filename, return it unchanged. If
51 the common directory of dir and absname is /, return absname
52 unchanged. If dir is not an absolute name, raise TypeError.
53
54 This is the posix specific version of relative_filename.
55
56 Example:
57 >>> from fileutil import relative_filename_posix
58 >>> relative_filename_posix("/usr/local/lib/", "/usr/local/lib/python")
59 'python'
60 >>> relative_filename_posix("/usr/local/lib/", "/usr/local/bin/python")
61 '../bin/python'
62 >>> relative_filename_posix("/usr/local/lib/", "/usr/bin/python")
63 '../../bin/python'
64 >>> relative_filename_posix("/usr/local/lib/", "/var/spool/mail")
65 '/var/spool/mail'
66 >>> relative_filename_posix("/home/", "xyzzy")
67 'xyzzy'
68 >>> relative_filename_posix("home/", "/xyzzy")
69 Traceback (most recent call last):
70 File "<stdin>", line 1, in ?
71 File "fileutil.py", line 42, in relative_filename_posix
72 raise TypeError("first argument must be an absolute filename")
73 TypeError: first argument must be an absolute filename
74 """
75 # for posix, the common part does exactly what we need, except for
76 # the special cases and input checking. Import posixpath explicitly
77 # for that to faciliate testing
78 import posixpath
79 if not posixpath.isabs(absname):
80 return absname
81
82 if not posixpath.isabs(dir):
83 raise TypeError("first argument must be an absolute filename")
84
85 dir = posixpath.normpath(dir)
86 absname = posixpath.normpath(absname)
87
88 return relative_filename_common(dir, absname, "/")
89
90 def relative_filename_nt(dir, absname):
91 r"""Return a filename relative to dir for the absolute file name absname.
92
93 If absname is already a relative filename or if dir and absname are
94 on different drives, return absname. If the common directory of dir
95 and absname is the drive's root directory, return absname. If dir is
96 not an absolute name or either name doesn't have a drive letter,
97 raise TypeError.
98
99 This is the nt specific version of relative_filename.
100
101 Example:
102 >>> from fileutil import relative_filename_nt
103 >>> relative_filename_nt(r"C:\Programme\Python", r"C:\Programme\Thuban")
104 '..\\Thuban'
105 >>> relative_filename_nt(r"C:\Programme\Python", r"D:\Programme\Thuban")
106 'D:\\Programme\\Thuban'
107 >>> relative_filename_nt(r"C:\Programme\Python", r"C:Programme")
108 'C:Programme'
109 >>> relative_filename_nt(r"C:Programme\Python", r"C:Programme")
110 Traceback (most recent call last):
111 File "<stdin>", line 1, in ?
112 File "fileutil.py", line 123, in relative_filename_nt
113 raise TypeError("first argument must be an absolute filename")
114 TypeError: first argument must be an absolute filename
115 >>> relative_filename_nt(r"\Programme\Python", r"\Programme")
116 Traceback (most recent call last):
117 File "<stdin>", line 1, in ?
118 File "fileutil.py", line 120, in relative_filename_nt
119 raise TypeError("Both parameters must have a drive letter")
120 TypeError: Both parameters must have a drive letter
121 """
122 # first check the parameters. Imort ntpath directly to facilitate
123 # testing on non-nt systems.
124 import ntpath
125
126 dir = ntpath.normpath(dir)
127 absname = ntpath.normpath(absname)
128
129 dir_drive, dir_rest = ntpath.splitdrive(dir)
130 absname_drive, absname_rest = ntpath.splitdrive(absname)
131 #print dir_drive, dir_rest
132 #print absname_drive, absname_rest
133 if not dir_drive or not absname_drive:
134 raise TypeError("Both parameters must have a drive letter")
135
136 if not ntpath.isabs(dir_rest):
137 raise TypeError("first argument must be an absolute filename")
138
139 # handle some special cases
140 if not ntpath.isabs(absname_rest):
141 return absname
142
143 if dir_drive != absname_drive:
144 return absname
145
146 # Now both dir_rest and absname_rest are absolute filenames without
147 # drive letter. We can now use the common part to determine the
148 # relative name
149 return relative_filename_common(dir_rest, absname_rest, "\\")
150
151
152 # bind the appriate version of relative_filename for the platform we're
153 # currently running on.
154 if os.name == "posix":
155 relative_filename = relative_filename_posix
156 elif os.name == "nt":
157 relative_filename = relative_filename_nt
158 else:
159 raise RuntimeError("No implementation of relative_filename"
160 " available for platform" + os.name)
161
162 __test__ = {"relative_filename_posix": relative_filename_posix,
163 "relative_filename_nt": relative_filename_nt}
164
165 # if run as a script, run doctest
166 def _test():
167 import doctest, fileutil
168 # Pass an isprivate function that always returns true so that only
169 # items in __test__ are tested
170 return doctest.testmod(fileutil, isprivate = lambda *args: 1)
171
172 if __name__ == "__main__":
173 _test()

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26