source: anuga_core/source/anuga/utilities/system_tools.py @ 6575

Last change on this file since 6575 was 6575, checked in by rwilson, 16 years ago

Removed usage of function available only in python 2.5.

File size: 8.4 KB
Line 
1"""Implementation of tools to do with system administration made as platform independent as possible.
2
3
4"""
5
6import sys
7import os
8
9def log_to_file(filename, s, verbose=False):
10    """Log string to file name
11    """
12
13    fid = open(filename, 'a')
14    if verbose: print s
15    fid.write(s + '\n')
16    fid.close()
17
18
19def get_user_name():
20    """Get user name provide by operating system
21    """
22
23    if sys.platform == 'win32':
24        #user = os.getenv('USERPROFILE')
25        user = os.getenv('USERNAME')
26    else:
27        user = os.getenv('LOGNAME')
28
29
30    return user   
31
32def get_host_name():
33    """Get host name provide by operating system
34    """
35
36    if sys.platform == 'win32':
37        host = os.getenv('COMPUTERNAME')
38    else:
39        host = os.uname()[1]
40
41
42    return host   
43
44def get_revision_number():
45    """Get the version number of the SVN
46    NOTE: This requires that the command svn is on the system PATH
47    (simply aliasing svn to the binary will not work)
48    """
49
50    # Create dummy info
51    #info = 'Revision: Version info could not be obtained.'
52    #info += 'A command line version of svn must be availbable '
53    #info += 'on the system PATH, access to the subversion '
54    #info += 'repository is necessary and the output must '
55    #info += 'contain a line starting with "Revision:"'
56   
57
58    #FIXME (Ole): Change this so that svn info is attempted first.
59    # If that fails, try to read a stored file with that same info (this would be created by e.g. the release script). Failing that, throw an exception.
60
61    #FIXME (Ole): Move this and store_version_info to utilities
62
63
64    try:
65        from anuga.stored_version_info import version_info
66    except:
67        msg = 'No version info stored and command "svn" is not '
68        msg += 'recognised on the system PATH.\n\n'
69        msg += 'If ANUGA has been installed from a distribution e.g. as '
70        msg += 'obtained from SourceForge,\n'
71        msg += 'the version info should be '
72        msg += 'available in the automatically generated file '
73        msg += 'stored_version_info.py\n'
74        msg += 'in the anuga root directory.\n'
75        msg += 'If run from a Subversion sandpit, '
76        msg += 'ANUGA will try to obtain the version info '
77        msg += 'by using the command: "svn info".\n'
78        msg += 'In this case, make sure svn is accessible on the system path. '
79        msg += 'Simply aliasing svn to the binary will not work. '
80        msg += 'Good luck!'
81
82        # No file available - try using Subversion
83        try:
84            # The null stuff is so this section fails quitly.
85            # This could cause the svn info command to fail due to
86            # the redirection being bad on some platforms.
87            # If that occurs then change this code.
88            if sys.platform[0:3] == 'win':
89                fid = os.popen('svn info 2> null')
90            else:
91                fid = os.popen('svn info 2>/dev/null')
92       
93        except:
94            raise Exception(msg)
95        else:
96            #print 'Got version from svn'           
97            version_info = fid.read()
98           
99            if version_info == '':
100                raise Exception(msg)   
101    else:
102        pass
103        #print 'Got version from file'
104
105           
106    for line in version_info.split('\n'):
107        if line.startswith('Revision:'):
108            break
109
110    fields = line.split(':')
111    msg = 'Keyword "Revision" was not found anywhere in text: %s' %version_info
112    assert fields[0].startswith('Revision'), msg           
113
114    try:
115        revision_number = int(fields[1])
116    except:
117        msg = 'Revision number must be an integer. I got %s' %fields[1]
118        msg += 'Check that the command svn is on the system path' 
119        raise Exception(msg)               
120       
121    return revision_number
122
123
124def store_version_info(destination_path='.', verbose=False):
125    """Obtain current version from Subversion and store it.
126   
127    Title: store_version_info()
128
129    Author: Ole Nielsen (Ole.Nielsen@ga.gov.au)
130
131    CreationDate: January 2006
132
133    Description:
134        This function obtains current version from Subversion and stores it
135        is a Python file named 'stored_version_info.py' for use with
136        get_version_info()
137
138        If svn is not available on the system PATH, an Exception is thrown
139    """
140
141    # Note (Ole): This function should not be unit tested as it will only
142    # work when running out of the sandpit. End users downloading the
143    # ANUGA distribution would see a failure.
144    #
145    # FIXME: This function should really only be used by developers (
146    # (e.g. for creating new ANUGA releases), so maybe it should move
147    # to somewhere else.
148   
149    import config
150
151    try:
152        fid = os.popen('svn info')
153    except:
154        msg = 'Command "svn" is not recognised on the system PATH'
155        raise Exception(msg)
156    else:   
157        txt = fid.read()
158        fid.close()
159
160
161        # Determine absolute filename
162        if destination_path[-1] != os.sep:
163            destination_path += os.sep
164           
165        filename = destination_path + config.version_filename
166
167        fid = open(filename, 'w')
168
169        docstring = 'Stored version info.\n\n'
170        docstring += 'This file provides the version for distributions '
171        docstring += 'that are not accessing Subversion directly.\n'
172        docstring += 'The file is automatically generated and should not '
173        docstring += 'be modified manually.\n'
174        fid.write('"""%s"""\n\n' %docstring)
175       
176        fid.write('version_info = """\n%s"""' %txt)
177        fid.close()
178
179
180        if verbose is True:
181            print 'Version info stored to %s' %filename
182
183def safe_crc(string):
184    """64 bit safe crc computation.
185
186       See Guido's 64 bit fix at http://bugs.python.org/issue1202           
187    """
188
189    from zlib import crc32
190    import os
191
192    x = crc32(string)
193       
194    if os.name == 'posix' and os.uname()[4] in ['x86_64', 'ia64']:
195        crcval = x - ((x & 0x80000000) << 1)
196    else:
197        crcval = x
198       
199    return crcval
200
201
202def compute_checksum(filename, max_length=2**20):
203    """Compute the CRC32 checksum for specified file
204
205    Optional parameter max_length sets the maximum number
206    of bytes used to limit time used with large files.
207    Default = 2**20 (1MB)
208    """
209
210    fid = open(filename, 'rb') # Use binary for portability
211    crcval = safe_crc(fid.read(max_length))
212    fid.close()
213
214    return crcval
215
216def get_pathname_from_package(package):
217    """Get pathname of given package (provided as string)
218
219    This is useful for reading files residing in the same directory as
220    a particular module. Typically, this is required in unit tests depending
221    on external files.
222
223    The given module must start from a directory on the pythonpath
224    and be importable using the import statement.
225
226    Example
227    path = get_pathname_from_package('anuga.utilities')
228
229    """
230
231    exec('import %s as x' %package)
232
233    path = x.__path__[0]
234   
235    return path
236
237    # Alternative approach that has been used at times
238    #try:
239    #    # When unit test is run from current dir
240    #    p1 = read_polygon('mainland_only.csv')
241    #except:
242    #    # When unit test is run from ANUGA root dir
243    #    from os.path import join, split
244    #    dir, tail = split(__file__)
245    #    path = join(dir, 'mainland_only.csv')
246    #    p1 = read_polygon(path)
247       
248           
249##
250# @brief Get list of variable names in an expression string.
251# @param source A string containing a python expression.
252# @return A list of variable name strings.
253# @note Throws SyntaxError exception if not a valid expression.
254def get_vars_in_expression(source):
255    '''Get list of variable names in a python expression.'''
256
257    import compiler
258    from compiler.ast import Node
259
260    ##
261    # @brief Internal recursive function.
262    # @param node An AST parse Node.
263    # @param var_list Input list of variables.
264    # @return An updated list of variables.
265    def get_vars_body(node, var_list=[]):
266        if isinstance(node, Node):
267            if node.__class__.__name__ == 'Name':
268                for child in node.getChildren():
269                    if child not in var_list:
270                        var_list.append(child)
271            for child in node.getChildren():
272                if isinstance(child, Node):
273                    for child in node.getChildren():
274                        var_list = get_vars_body(child, var_list)
275                    break
276##            if any(isinstance(child, Node) for child in node.getChildren()):
277##                for child in node.getChildren():
278##                    var_list = get_vars_body(child, var_list)
279
280        return var_list
281
282    return get_vars_body(compiler.parse(source))
Note: See TracBrowser for help on using the repository browser.