1 """
2 Functions and classes to simplify dealing with paths.
3
4 For portable code:
5 - specify paths in unix (rather than Windows) style;
6 - use resolve_path() for paths to existing files to be read,
7 and normalize_path() for paths to new files to be written.
8
9 The location in which new files are created by default can be
10 controlled by the output_path module attribute, which applies
11 whenever a particular location is not specified explicitly.
12
13 $Id: filepath.py 10672 2009-10-28 01:00:50Z ceball $
14 """
15 __version__='$Revision: 10672 $'
16
17 import os.path
18 import sys
19
20 import param
21
22
23
24 import socket,tempfile
26 """Determine whether a given directory is writable in a portable manner.
27
28 :Parameters:
29 - dir: string
30 A string represeting a path to a directory on the filesystem.
31
32 :Returns:
33 True or False.
34 """
35
36
37
38
39
40
41 prefix = 'dummy_%s_%s_' % (socket.gethostname(),os.getpid())
42 try:
43 tmp = tempfile.TemporaryFile(prefix=prefix,dir=dir)
44 except OSError:
45 return False
46
47
48 tmp.close()
49 return True
50
51
53 """
54 Filename is a Parameter that can be set to a string specifying the
55 path of a file (in unix style), and returns it in the format of
56 the user's operating system. Additionally, the specified path can
57 be absolute or relative to:
58
59 * any of the paths specified in the search_paths attribute;
60
61 * any of the paths searched by resolve_path() (see doc for that
62 function).
63 """
64 __slots__ = ['search_paths']
65
66 - def __init__(self,default=None,search_paths=[],**params):
69
70
72 """
73 Call Parameter's __set__, but warn if the file cannot be found.
74 """
75 try:
76 resolve_path(val,self.search_paths)
77 except IOError, e:
78 param.Parameterized(name="%s.%s"%(obj.name,self._attrib_name)).warning('%s'%(e.args[0]))
79
80 super(Filename,self).__set__(obj,val)
81
88
97
98
99 import topo
100 package_path = os.path.split(topo.__file__)[0]
101
102
103
104
105 application_path = os.path.split(os.path.split(sys.executable)[0])[0]
106
107
108
109 if is_writable(application_path):
110 output_path = application_path
111 else:
112 home_topographica = os.path.join(os.path.expanduser("~"),'topographica')
113 if not os.path.exists(home_topographica):
114 os.mkdir(home_topographica)
115 output_path = home_topographica
116
117
119 """
120 Find the path to an existing file, searching in the specified
121 search paths if the filename is not absolute, and converting a
122 UNIX-style path to the current OS's format if necessary.
123
124 To turn a supplied relative path into an absolute one, the path is
125 appended to each path in (search_paths+the current working
126 directory+the application's base path), in that order, until the
127 file is found.
128
129 (Similar to Python's os.path.abspath(), except more search paths
130 than just os.getcwd() can be used, and the file must exist.)
131
132 An IOError is raised if the file is not found anywhere.
133 """
134 path = os.path.normpath(path)
135
136 if os.path.isabs(path):
137 if os.path.isfile(path):
138 return path
139 else:
140 raise IOError('File "%s" not found.'%path)
141 else:
142 all_search_paths = search_paths or [] + [os.getcwd()] + [output_path] + [package_path] + [application_path]
143
144 paths_tried = []
145 for prefix in all_search_paths:
146 try_path = os.path.join(os.path.normpath(prefix),path)
147 if os.path.isfile(try_path): return try_path
148 paths_tried.append(try_path)
149
150 raise IOError('File "'+os.path.split(path)[1]+'" was not found in the following place(s): '+str(paths_tried)+'.')
151
152
154 """
155 Convert a UNIX-style path to the current OS's format,
156 typically for creating a new file or directory.
157
158 If the path is not already absolute, it will be made
159 absolute (using the specified prefix, which defaults
160 to filepath.output_path) in the process.
161
162 (Should do the same as Python's os.path.abspath(), except
163 using the specified prefix rather than os.getcwd().)
164 """
165 if not prefix:
166 prefix = output_path
167
168 if not os.path.isabs(path):
169 path = os.path.join(os.path.normpath(prefix),path)
170
171 return os.path.normpath(path)
172