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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 374 - (hide annotations)
Mon Jan 27 14:20:02 2003 UTC (22 years, 1 month ago) by jan
Original Path: trunk/thuban/Thuban/Lib/fileutil.py
File MIME type: text/x-python
File size: 6468 byte(s)
Replace user string by _() for i18n.

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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26