source: trunk/anuga_core/source/anuga/utilities/file_utils.py @ 8109

Last change on this file since 8109 was 8109, checked in by steve, 13 years ago

THere were some missing definitions of exceptions in sww.py. Might be other files which are missing these definitions

File size: 10.1 KB
Line 
1""" Generic file utilities for creating, parsing deleting
2    and naming files in a manner consistent across ANUGA.
3"""
4
5
6import os, sys
7import csv
8import numpy as num
9import shutil
10import log
11
12from exceptions import IOError
13
14def make_filename(s):
15    """Transform argument string into a standard filename
16   
17        Convert a possible filename into a standard form.
18        s Filename to process.
19        The new filename string.
20    """
21
22    s = s.strip()
23    s = s.replace(' ', '_')
24    s = s.replace('(', '')
25    s = s.replace(')', '')
26    s = s.replace('__', '_')
27
28    return s
29
30
31def check_dir(path, verbose=None):
32    """Check that specified path exists.
33    If path does not exist it will be created if possible
34
35    USAGE:
36       checkdir(path, verbose):
37
38    ARGUMENTS:
39        path -- Directory
40        verbose -- Flag verbose output (default: None)
41
42    RETURN VALUE:
43        Verified path including trailing separator
44    """
45
46    import os.path
47
48    if sys.platform in ['nt', 'dos', 'win32', 'what else?']:
49        unix = 0
50    else:
51        unix = 1
52
53    # add terminal separator, if it's not already there
54    if path[-1] != os.sep:
55        path = path + os.sep
56
57    # expand ~ or ~username in path
58    path = os.path.expanduser(path)
59
60    # create directory if required
61    if not (os.access(path, os.R_OK and os.W_OK) or path == ''):
62        try:
63            exitcode = os.mkdir(path)
64
65            # Change access rights if possible
66            if unix:
67                exitcode = os.system('chmod 775 ' + path)
68            else:
69                pass  # FIXME: What about access rights under Windows?
70
71            if verbose: log.critical('MESSAGE: Directory %s created.' % path)
72        except:
73            log.critical('WARNING: Directory %s could not be created.' % path)
74            if unix:
75                path = '/tmp/'
76            else:
77                path = 'C:' + os.sep
78
79            log.critical("Using directory '%s' instead" % path)
80
81    return path
82
83
84##
85# @brief Delete directory and all sub-directories.
86# @param path Path to the directory to delete.
87def del_dir(path):
88    """Recursively delete directory path and all its contents
89    """
90
91    if os.path.isdir(path):
92        for file in os.listdir(path):
93            X = os.path.join(path, file)
94
95            if os.path.isdir(X) and not os.path.islink(X):
96                del_dir(X)
97            else:
98                try:
99                    os.remove(X)
100                except:
101                    log.critical("Could not remove file %s" % X)
102
103        os.rmdir(path)
104
105
106##
107# @brief ??
108# @param path
109# @param __func__
110# @param verbose True if this function is to be verbose.
111# @note ANOTHER OPTION, IF NEED IN THE FUTURE, Nick B 7/2007
112def rmgeneric(path, func, verbose=False):
113    ERROR_STR= """Error removing %(path)s, %(error)s """
114
115    try:
116        func(path)
117        if verbose: log.critical('Removed %s' % path)
118    except OSError, (errno, strerror):
119        log.critical(ERROR_STR % {'path' : path, 'error': strerror })
120
121
122##
123# @brief Remove directory and all sub-directories.
124# @param path Filesystem path to directory to remove.
125# @param verbose True if this function is to be verbose.
126def removeall(path, verbose=False):
127    if not os.path.isdir(path):
128        return
129
130    for x in os.listdir(path):
131        fullpath = os.path.join(path, x)
132        if os.path.isfile(fullpath):
133            f = os.remove
134            rmgeneric(fullpath, f)
135        elif os.path.isdir(fullpath):
136            removeall(fullpath)
137            f = os.rmdir
138            rmgeneric(fullpath, f, verbose)
139
140
141##
142# @brief Create a standard filename.
143# @param datadir Directory where file is to be created.
144# @param filename Filename 'stem'.
145# @param format Format of the file, becomes filename extension.
146# @param size Size of file, becomes part of filename.
147# @param time Time (float), becomes part of filename.
148# @return The complete filename path, including directory.
149# @note The containing directory is created, if necessary.
150def create_filename(datadir, filename, format, size=None, time=None):
151    FN = check_dir(datadir) + filename
152
153    if size is not None:
154        FN += '_size%d' % size
155
156    if time is not None:
157        FN += '_time%.2f' % time
158
159    FN += '.' + format
160
161    return FN
162
163
164##
165# @brief Get all files with a standard name and a given set of attributes.
166# @param datadir Directory files must be in.
167# @param filename Filename stem.
168# @param format Filename extension.
169# @param size Filename size.
170# @return A list of fielnames (including directory) that match the attributes.
171def get_files(datadir, filename, format, size):
172    """Get all file (names) with given name, size and format
173    """
174
175    import glob
176
177    dir = check_dir(datadir)
178    pattern = dir + os.sep + filename + '_size=%d*.%s' % (size, format)
179
180    return glob.glob(pattern)
181
182
183##
184# @brief Find all files in a directory that contain a given string.
185# @param look_in_dir Path to the directory to look in.
186# @param base_name String that files must contain.
187# @param verbose True if this function is to be verbose.
188def get_all_directories_with_name(look_in_dir='', base_name='', verbose=False):
189    '''
190    Finds all the directories in a "look_in_dir" which contains a "base_name".
191
192    Returns: a list of strings
193
194    Usage:     iterate_over = get_all_directories_with_name(dir, name)
195    then:      for swwfile in iterate_over:
196                   do stuff
197
198    Check "export_grids" and "get_maximum_inundation_data" for examples
199    '''
200
201    if look_in_dir == "":
202        look_in_dir = "."                                  # Unix compatibility
203
204    dir_ls = os.listdir(look_in_dir)
205    iterate_over = [x for x in dir_ls if base_name in x]
206
207    if len(iterate_over) == 0:
208        msg = 'No files of the base name %s' % base_name
209        raise IOError, msg
210
211    if verbose: log.critical('iterate over %s' % iterate_over)
212
213    return iterate_over
214
215
216
217##
218# @brief Find all SWW files in a directory with given stem name.
219# @param look_in_dir The directory to look in.
220# @param base_name The file stem name.
221# @param verbose True if this function is to be verbose.
222# @return A list of found filename strings.
223# @note Will accept 'base_name' with or without '.sww' extension.
224# @note If no files found, raises IOError exception.
225def get_all_swwfiles(look_in_dir='', base_name='', verbose=False):
226    '''
227    Finds all the sww files in a "look_in_dir" which contains a "base_name".
228    will accept base_name with or without the extension ".sww"
229
230    Returns: a list of strings
231
232    Usage:     iterate_over = get_all_swwfiles(dir, name)
233    then
234               for swwfile in iterate_over:
235                   do stuff
236
237    Check "export_grids" and "get_maximum_inundation_data" for examples
238    '''
239
240    # plus tests the extension
241    name, extension = os.path.splitext(base_name)
242
243    if extension != '' and extension != '.sww':
244        msg = 'file %s%s must be a NetCDF sww file!' % (base_name, extension)
245        raise IOError, msg
246
247    if look_in_dir == "":
248        look_in_dir = "."                                   # Unix compatibility
249
250    dir_ls = os.listdir(look_in_dir)
251    iterate_over = [x[:-4] for x in dir_ls if name in x and x[-4:] == '.sww']
252    if len(iterate_over) == 0:
253        msg = 'No files of the base name %s' % name
254        raise IOError, msg
255
256    if verbose: log.critical('iterate over %s' % iterate_over)
257
258    return iterate_over
259
260
261##
262# @brief Find all files in a directory that contain a string and have extension.
263# @param look_in_dir Path to the directory to look in.
264# @param base_name Stem filename of the file(s) of interest.
265# @param extension Extension of the files to look for.
266# @param verbose True if this function is to be verbose.
267# @return A list of found filename strings.
268# @note If no files found, raises IOError exception.
269def get_all_files_with_extension(look_in_dir='',
270                                 base_name='',
271                                 extension='.sww',
272                                 verbose=False):
273    '''Find all files in a directory with given stem name.
274    Finds all the sww files in a "look_in_dir" which contains a "base_name".
275
276    Returns: a list of strings
277
278    Usage:     iterate_over = get_all_swwfiles(dir, name)
279    then
280               for swwfile in iterate_over:
281                   do stuff
282
283    Check "export_grids" and "get_maximum_inundation_data" for examples
284    '''
285
286    # plus tests the extension
287    name, ext = os.path.splitext(base_name)
288
289    if ext != '' and ext != extension:
290        msg = 'base_name %s must be a file with %s extension!' \
291              % (base_name, extension)
292        raise IOError, msg
293
294    if look_in_dir == "":
295        look_in_dir = "."                               # Unix compatibility
296
297    dir_ls = os.listdir(look_in_dir)
298    iterate_over = [x[:-4] for x in dir_ls if name in x and x[-4:] == extension]
299
300    if len(iterate_over) == 0:
301        msg = 'No files of the base name %s in %s' % (name, look_in_dir)
302        raise IOError, msg
303
304    if verbose: log.critical('iterate over %s' % iterate_over)
305
306    return iterate_over
307
308
309
310
311def copy_code_files(dir_name, filename1, filename2=None, verbose=False):
312    """Copies "filename1" and "filename2" to "dir_name".
313
314    Each 'filename' may be a string or list of filename strings.
315
316    Filenames must be absolute pathnames
317    """
318
319    ##
320    # @brief copies a file or sequence to destination directory.
321    # @param dest The destination directory to copy to.
322    # @param file A filename string or sequence of filename strings.
323    def copy_file_or_sequence(dest, file):
324        if hasattr(file, '__iter__'):
325            for f in file:
326                shutil.copy(f, dir_name)
327                if verbose:
328                    log.critical('File %s copied' % f)
329        else:
330            shutil.copy(file, dir_name)
331            if verbose:
332                log.critical('File %s copied' % file)
333
334    # check we have a destination directory, create if necessary
335    if not os.path.isdir(dir_name):
336        if verbose:
337            log.critical('Make directory %s' % dir_name)
338        os.mkdir(dir_name, 0777)
339
340    if verbose:
341        log.critical('Output directory: %s' % dir_name)       
342
343    copy_file_or_sequence(dir_name, filename1)
344
345    if not filename2 is None:
346        copy_file_or_sequence(dir_name, filename2)
Note: See TracBrowser for help on using the repository browser.