/[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 2734 - (hide annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 7967 byte(s)
made a copy
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 frank 1148 import os
15 bh 6 import os.path
16 frank 1148 from tempfile import mktemp
17    
18 jan 1885 from string import join
19 bh 6
20 jan 374 from Thuban import _
21 bh 6
22     def relative_filename_common(dir, absname, sep):
23     """Return a filename relative to dir for the absolute file name absname.
24     This is part the posix and nt versions have in common. Both dir and
25     absname are assumed to be normalized (as done with os.normpath)
26     absolute filenames without drive letters. sep is the platform
27     specific directory separator.
28     """
29    
30     # split the filenames into their components. remove the first item
31     # since it will be always empty because both names are absolute.
32 jan 1885 dir_parts = dir.split(sep)[1:]
33     absname_parts = absname.split(sep)[1:]
34 bh 6
35     # count the number of common parts at the start of dir_parts and
36     # absname_parts
37     max_common = min(len(dir_parts), len(absname_parts))
38     common = 0
39     while common < max_common and dir_parts[common] == absname_parts[common]:
40     common = common + 1
41    
42     # If the common part is the root directory, return absname
43     if common == 0:
44     return absname
45    
46     # for each directory under the common part prepend a '..'.
47     rel_parts = (len(dir_parts) - common) * ['..'] + absname_parts[common:]
48     return join(rel_parts, sep)
49    
50    
51     def relative_filename_posix(dir, absname):
52     """Return a filename relative to dir for the absolute file name absname.
53    
54     If absname is already a relative filename, return it unchanged. If
55     the common directory of dir and absname is /, return absname
56     unchanged. If dir is not an absolute name, raise TypeError.
57    
58     This is the posix specific version of relative_filename.
59    
60     Example:
61     >>> from fileutil import relative_filename_posix
62     >>> relative_filename_posix("/usr/local/lib/", "/usr/local/lib/python")
63     'python'
64     >>> relative_filename_posix("/usr/local/lib/", "/usr/local/bin/python")
65     '../bin/python'
66     >>> relative_filename_posix("/usr/local/lib/", "/usr/bin/python")
67     '../../bin/python'
68     >>> relative_filename_posix("/usr/local/lib/", "/var/spool/mail")
69     '/var/spool/mail'
70     >>> relative_filename_posix("/home/", "xyzzy")
71     'xyzzy'
72     >>> relative_filename_posix("home/", "/xyzzy")
73     Traceback (most recent call last):
74     File "<stdin>", line 1, in ?
75     File "fileutil.py", line 42, in relative_filename_posix
76     raise TypeError("first argument must be an absolute filename")
77     TypeError: first argument must be an absolute filename
78     """
79     # for posix, the common part does exactly what we need, except for
80     # the special cases and input checking. Import posixpath explicitly
81     # for that to faciliate testing
82     import posixpath
83     if not posixpath.isabs(absname):
84 bh 339 return absname
85 bh 6
86     if not posixpath.isabs(dir):
87 jan 374 raise TypeError(_("first argument must be an absolute filename"))
88 bh 6
89     dir = posixpath.normpath(dir)
90     absname = posixpath.normpath(absname)
91    
92     return relative_filename_common(dir, absname, "/")
93    
94     def relative_filename_nt(dir, absname):
95     r"""Return a filename relative to dir for the absolute file name absname.
96    
97     If absname is already a relative filename or if dir and absname are
98     on different drives, return absname. If the common directory of dir
99     and absname is the drive's root directory, return absname. If dir is
100     not an absolute name or either name doesn't have a drive letter,
101     raise TypeError.
102    
103     This is the nt specific version of relative_filename.
104    
105     Example:
106     >>> from fileutil import relative_filename_nt
107     >>> relative_filename_nt(r"C:\Programme\Python", r"C:\Programme\Thuban")
108     '..\\Thuban'
109     >>> relative_filename_nt(r"C:\Programme\Python", r"D:\Programme\Thuban")
110     'D:\\Programme\\Thuban'
111     >>> relative_filename_nt(r"C:\Programme\Python", r"C:Programme")
112     'C:Programme'
113     >>> relative_filename_nt(r"C:Programme\Python", r"C:Programme")
114     Traceback (most recent call last):
115     File "<stdin>", line 1, in ?
116     File "fileutil.py", line 123, in relative_filename_nt
117     raise TypeError("first argument must be an absolute filename")
118     TypeError: first argument must be an absolute filename
119     >>> relative_filename_nt(r"\Programme\Python", r"\Programme")
120     Traceback (most recent call last):
121     File "<stdin>", line 1, in ?
122     File "fileutil.py", line 120, in relative_filename_nt
123     raise TypeError("Both parameters must have a drive letter")
124     TypeError: Both parameters must have a drive letter
125     """
126     # first check the parameters. Imort ntpath directly to facilitate
127     # testing on non-nt systems.
128     import ntpath
129    
130     dir = ntpath.normpath(dir)
131     absname = ntpath.normpath(absname)
132    
133     dir_drive, dir_rest = ntpath.splitdrive(dir)
134     absname_drive, absname_rest = ntpath.splitdrive(absname)
135     #print dir_drive, dir_rest
136     #print absname_drive, absname_rest
137     if not dir_drive or not absname_drive:
138 jan 374 raise TypeError(_("Both parameters must have a drive letter"))
139 bh 6
140     if not ntpath.isabs(dir_rest):
141 jan 374 raise TypeError(_("first argument must be an absolute filename"))
142 bh 6
143     # handle some special cases
144     if not ntpath.isabs(absname_rest):
145 bh 339 return absname
146 bh 6
147     if dir_drive != absname_drive:
148     return absname
149    
150     # Now both dir_rest and absname_rest are absolute filenames without
151     # drive letter. We can now use the common part to determine the
152     # relative name
153     return relative_filename_common(dir_rest, absname_rest, "\\")
154    
155 frank 1148 def get_application_dir():
156 jonathan 1188 """Determine the path to the .thuban directory. Create the directory
157     if it doesn't exist.
158 bh 6
159 frank 1148 Under posix systems use the os.expanduser() method.
160     Under Win32 try to read the "Explorer/Shell Folders/" value "AppData".
161     """
162    
163     if os.name == 'posix':
164 jonathan 1188 dir = os.path.expanduser("~/.thuban")
165     if not os.path.isdir(dir):
166     os.mkdir(dir)
167     return dir
168 frank 1148 elif os.name == 'nt':
169     regkey = 1
170     try:
171     import _winreg as wreg
172     except ImportError:
173     regkey = 0
174    
175     if regkey:
176     try:
177     key = wreg.OpenKey(wreg.HKEY_CURRENT_USER,
178     "Software\\Microsoft\\Windows\\CurrentVersion\\"\
179     "Explorer\\Shell Folders")
180 frank 1152 dir = wreg.QueryValueEx(key, "AppData")[0]
181     dir = os.path.join(dir, "thuban")
182 frank 1148 except:
183     regkey = 0
184    
185 frank 1152 if not regkey:
186 frank 1148 # The fallback. This should result in something like the
187     # user directory ...
188     guess = os.path.dirname(
189     os.path.dirname(os.path.dirname(mktemp()))
190     )
191     dir = os.path.join(guess, "thuban")
192     if not os.path.isdir(dir):
193     os.mkdir(dir)
194    
195     return dir
196    
197     else:
198     raise RuntimeError(_("No implementation of get_application_dir"
199     " available for platform") + os.name)
200    
201 bh 339 # bind the appropriate version of relative_filename for the platform
202     # we're currently running on.
203 bh 6 if os.name == "posix":
204     relative_filename = relative_filename_posix
205     elif os.name == "nt":
206     relative_filename = relative_filename_nt
207     else:
208 jan 374 raise RuntimeError(_("No implementation of relative_filename"
209     " available for platform") + os.name)
210 bh 6
211     __test__ = {"relative_filename_posix": relative_filename_posix,
212     "relative_filename_nt": relative_filename_nt}
213    
214     # if run as a script, run doctest
215     def _test():
216     import doctest, fileutil
217     # Pass an isprivate function that always returns true so that only
218     # items in __test__ are tested
219     return doctest.testmod(fileutil, isprivate = lambda *args: 1)
220    
221     if __name__ == "__main__":
222     _test()

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26