00001
00002
00003
00004 __file__ = 'fileUtils.py'
00005 __title__ = 'This module helps managing files and directories.'
00006 __version__ = '0.1'
00007 __author__ = 'Olivier Boudeville (olivier.boudeville@online.fr)'
00008 __project__ = 'Ceylan'
00009 __creationDate__= '2004, February 1'
00010 __comments__ = ""
00011 __source__ = 'Mark Pilgrim, http://diveintopython.org/, and al.'
00012 __doc__ = __title__ + '\n' + __comments__
00013
00014
00015
00016 import sys, types, string, os, os.path, ConfigParser, md5
00017
00018
00019 from generalUtils import *
00020
00021
00022 class FileUtilsException( GeneralUtilsException ) :
00023 """Base class for fileUtils exceptions."""
00024
00025
00026 def updateConfigurationFromFile( configDic, configFile ) :
00027 """
00028 Updates configuration dictionary 'configDic' with informations found in file 'configFile'.
00029 Warning : uppercase letters should not be used in configuration files, since ConfigParser
00030 downcase them.
00031 """
00032
00033 try:
00034 myParser = ConfigParser.ConfigParser()
00035 myParser.read( configFile )
00036 optionsList = myParser.options( 'Options' )
00037
00038 except:
00039 print >> sys.stderr, 'Cannot open or read configuration file %s. Using default settings.' % ( configFile, )
00040 return configDic
00041 for option in optionsList:
00042 if configDic.has_key( option ) :
00043
00044 configDic[ option ] = myParser.get( 'Options', option )
00045 else :
00046 print >> sys.stderr, "Warning : ignoring option <%s>, found in configuration file but not registered." % ( option, )
00047
00048
00049 def findNextNewDirectoryName( destinationPrefix ):
00050 """
00051 Returns a unique name : find next possible new directory name by adding
00052 increasing numbers to the end of the names of pre existing ones.
00053 Example : OSDL-data -> OSDL-data-1, OSDL-data-17 -> OSDL-data-18
00054 """
00055 dir_count = 0
00056 dest_dir = destinationPrefix
00057 while os.path.exists( dest_dir ) :
00058 dir_count += 1
00059 dest_dir = '%s%s%s' % ( destinationPrefix, '-' , str( dir_count ) )
00060 return dest_dir
00061
00062
00063 def checkDirectory( directoryName ) :
00064 """Checks if corresponding directory exists. If not, raises FileUtilsException."""
00065
00066 if not os.path.exists( directoryName ) :
00067 raise FileUtilsException, 'Cannot find directory <%s>.' % ( directoryName, )
00068 if not os.path.isdir( directoryName ) :
00069 raise FileUtilsException, '<%s> is not a directory.' % ( directoryName, )
00070 return directoryName
00071
00072
00073 def checkFile( filename ) :
00074 """Checks if corresponding file exists. If not, raises FileUtilsException."""
00075 if not os.path.exists( filename ) :
00076 raise FileUtilsException, 'Cannot find file <%s>.' % ( filename, )
00077 if not os.path.isfile( filename ) :
00078 raise FileUtilsException, '<%s> is not a file.' % ( filename, )
00079 return filename
00080
00081
00082 def convertIntoFileName( name ) :
00083 """Converts specified name into a valid filename for most file systems."""
00084
00085 return name.replace( '.', '-' ).replace( ' ', '-' )
00086
00087
00088 def filesAllExist( filenamesList ) :
00089 """Returns true if and only if all files in the list exist."""
00090 for f in filenamesList:
00091 if not os.path.isfile( f ) :
00092 display.debug( 'File %s does not exist.' )
00093 return false
00094 return True
00095
00096
00097 def isContent( filename ) :
00098 """Returns true if and only if filename corresponds to a content file."""
00099 return os.path.isfile( filename ) and ( isGraphics( filename ) or isSound( filename ) )
00100
00101
00102 def isGraphics( filename ) :
00103 """Returns true if and only if filename corresponds to a picture file."""
00104 graphics_extension_list = [ '.jpg', '.jpeg', '.tiff', '.png', '.gif', '.bmp' ]
00105 return os.path.splitext( filename )[1].lower() in graphics_extension_list
00106
00107
00108 def isSound( filename ) :
00109 """Returns true if and only if filename corresponds to a sound file."""
00110 sound_extension_list = [ '.wav', '.mp3', '.ogg', '.raw' ]
00111 return os.path.splitext( filename )[1].lower() in sound_extension_list
00112
00113
00114 def getParentDirectory( directoryName ) :
00115 """Returns the name of the parent directory of directoryName."""
00116 return os.path.dirname( directoryName )
00117
00118
00119 def getChildrenDirectories( directoryName ) :
00120 """
00121 Returns a list made of the (relative) names of the children directories of directoryName.
00122 """
00123 return [ elem for elem in os.listdir( directoryName ) if os.path.isdir( os.path.join( directoryName, elem ) ) ]
00124
00125
00126 def getFilesInDir( directoryName ) :
00127 """Returns a list made of the (relative) names of the files in directory directoryName."""
00128
00129 fileList = []
00130 for elem in os.listdir( directoryName ) :
00131 if os.path.isfile( os.path.join( directoryName, elem) ) :
00132 fileList.append( elem )
00133 return fileList
00134
00135
00136 def getDirectoryElements( directoryName ) :
00137 """
00138 Returns a pair, the list of subdirectories of directoryName and the list of
00139 the files in directoryName, all of them relatively to that directory, no absolute path.
00140 """
00141 directories_list = []
00142 files_list = []
00143 for elem in os.listdir( directoryName ) :
00144 if os.path.isdir( os.path.join( directoryName, elem) ) :
00145 directories_list.append( elem )
00146 elif os.path.isfile( os.path.join( directoryName, elem) ) :
00147 files_list.append( elem )
00148 else:
00149 raise FileUtilsException, 'In directory %s, %s was found being neither directory or file.' % ( elem,)
00150 return directories_list, files_list
00151
00152
00153 def addPrefixToFileList( prefix, filesList ) :
00154 """All files or directories in filesList will be prefixed with prefix."""
00155
00156 return [ os.path.join( prefix, file) for file in filesList]
00157
00158
00159 def scanDirectoryForContent( directoryName ) :
00160 """Scans provided directory and return a 3-item tuple with graphics files, sound files and other files that were spotted."""
00161
00162 if not os.path.isdir( directoryName ):
00163 raise ValueError, "Unable to scan directory %s, as it does not exist." % ( directoryName, )
00164 graphics_list = []
00165 sounds_list = []
00166 unknown_list = []
00167 for f in getFilesInDir( directoryName ) :
00168 if isGraphics( f ) :
00169 graphics_list.append( f )
00170 elif isSound( f ) :
00171 sounds_list.append( f )
00172 else :
00173 unknown_list.append( f )
00174
00175 return graphics_list, sounds_list, unknown_list
00176
00177
00178 def getAllFilePathsFromRoot( directoryName ) :
00179 """Returns a list of all files relative paths found from specified directory."""
00180
00181 if not os.path.isdir( directoryName ):
00182 raise ValueError, "Unable to scan directory %s, as it does not exist." % ( directoryName, )
00183
00184 subdirs = getChildrenDirectories(directoryName)
00185 local_files = [ os.path.join(directoryName,dir) for dir in getFilesInDir(directoryName) ]
00186
00187 for dir in subdirs:
00188 local_files += getAllFilePathsFromRoot(
00189 os.path.join(directoryName,dir) )
00190
00191 return local_files
00192
00193
00194 def getAllRelativeFilePathsFromRoot( directoryName ) :
00195 return getAllRelativeFilePathsFromRootHelper( ".", directoryName )
00196
00197
00198 def getAllRelativeFilePathsFromRootHelper( directorySuffixName, baseRoot ) :
00199 """Returns a list of all files relative paths found from specified directory."""
00200
00201 complete_dir = os.path.join( baseRoot, directorySuffixName )
00202
00203 if not os.path.isdir( complete_dir ):
00204 raise ValueError, "Unable to scan directory %s, as it does not exist." % ( complete_dir, )
00205
00206 subdirs = getChildrenDirectories(complete_dir)
00207 local_files = [ os.path.join(directorySuffixName,filename) for filename in getFilesInDir(complete_dir) ]
00208
00209 for dir in subdirs:
00210 local_files += getAllRelativeFilePathsFromRootHelper(
00211 os.path.join(directorySuffixName,dir), baseRoot )
00212
00213 return local_files
00214
00215
00216 def getMD5codeFor(file_path):
00217 """"Returns the MD5 code corresponding to the file in specified path."""
00218 checkFile(file_path)
00219 scanned_file = file(file_path,'rb')
00220 return md5.new( scanned_file.read() ).hexdigest()
00221
00222
00223 def backup( fileToBackup ) :
00224 """
00225 Backups a file. Non-existing file will be ignored. Backup file will have the suffix '.bak'.
00226 """
00227
00228 backExtension = '.bak'
00229
00230 backupFile = fileToBackup + backExtension
00231
00232 if os.path.exists( backupFile ) :
00233 try:
00234 os.remove( backupFile )
00235 except OSError:
00236 print >> sys.stderr, 'Cannot remove %s' % ( backupFile, )
00237 return sys.exc_info()
00238
00239 if os.path.exists( fileToBackup ):
00240 try:
00241 os.rename( fileToBackup, backupFile )
00242 except OSError:
00243 print >> sys.stderr, 'Cannot rename %s' % ( fileToBackup, )
00244 return sys.exc_info()
00245
00246
00247
00248 if __name__ == "__main__":
00249 print __doc__
00250
00251