Package translate :: Package storage :: Module factory
[hide private]
[frames] | no frames]

Source Code for Module translate.storage.factory

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  #  
  4  # Copyright 2006 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  8  # translate is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate is distributed in the hope that it will be useful, 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16  # GNU General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21   
 22  """factory methods to build real storage objects that conform to base.py""" 
 23   
 24  import os 
 25  from gzip import GzipFile 
 26  try: 
 27      # bz2 is not available on python 2.3 
 28      from bz2 import BZ2File 
 29  except ImportError: 
 30      BZ2File = None 
 31  import sys 
 32   
 33  from translate.storage import base 
 34  from translate.storage import csvl10n 
 35  from translate.storage import mo 
 36  from translate.storage import po 
 37  from translate.storage import qm 
 38  from translate.storage import wordfast 
 39  #Let's try to import the XML formats carefully. They might fail if the user 
 40  #doesn't have lxml installed. Let's try to continue gracefully, but print an  
 41  #informative warning. 
 42  try: 
 43      #Although poxliff is unused in this module, it is referenced in test_factory 
 44      from translate.storage import poxliff 
 45      from translate.storage import qph 
 46      from translate.storage import tbx 
 47      from translate.storage import tmx 
 48      from translate.storage import ts2 as ts 
 49      from translate.storage import xliff 
 50      support_xml = True 
 51  except ImportError, e: 
 52      print >> sys.stderr, str(e) 
 53      support_xml = False 
 54   
 55   
 56  #TODO: Monolingual formats (with template?) 
 57   
 58  classes = { 
 59             "csv": csvl10n.csvfile,  
 60             "po": po.pofile, "pot": po.pofile,  
 61             "mo": mo.mofile, "gmo": mo.mofile,  
 62             "qm": qm.qmfile,  
 63             "_wftm": wordfast.WordfastTMFile, 
 64            } 
 65  """Dictionary of file extensions and their associated class.   
 66   
 67  _ext is a pseudo extension, that is their is no real extension by that name.""" 
 68   
 69  if support_xml: 
 70      classes.update({ 
 71             "qph": qph.QphFile, 
 72             "tbx": tbx.tbxfile, 
 73             "tmx": tmx.tmxfile,  
 74             "ts": ts.tsfile, 
 75             "xliff": xliff.xlifffile, "xlf": xliff.xlifffile, 
 76      }) 
 77   
 78  decompressclass = { 
 79      'gz': GzipFile, 
 80  } 
 81  if BZ2File: 
 82      decompressclass['bz2'] = BZ2File 
 83   
84 -def _examine_txt(storefile):
85 """Determine the true filetype for a .txt file""" 86 if isinstance(storefile, basestring) and os.path.exists(storefile): 87 storefile = open(storefile) 88 try: 89 start = storefile.read(600).strip() 90 except AttributeError: 91 raise ValueError("Need to read object to determine type") 92 # Some encoding magic for Wordfast 93 if wordfast.TAB_UTF16 in start.split("\n")[0]: 94 encoding = 'utf-16' 95 else: 96 encoding = 'iso-8859-1' 97 start = start.decode(encoding).encode('utf-8') 98 if '%Wordfast TM' in start: 99 pseudo_extension = '_wftm' 100 else: 101 raise ValueError("Failed to guess file type.") 102 storefile.seek(0) 103 return pseudo_extension
104 105 hiddenclasses = {"txt": _examine_txt} 106
107 -def _guessextention(storefile):
108 """Guesses the type of a file object by looking at the first few characters. 109 The return value is a file extention .""" 110 start = storefile.read(300).strip() 111 if '<xliff ' in start: 112 extention = 'xlf' 113 elif 'msgid "' in start: 114 extention = 'po' 115 elif '%Wordfast TM' in start: 116 extention = 'txt' 117 elif '<!DOCTYPE TS>' in start: 118 extention = 'ts' 119 else: 120 raise ValueError("Failed to guess file type.") 121 storefile.seek(0) 122 return extention
123
124 -def _getdummyname(storefile):
125 """Provides a dummy name for a file object without a name attribute, by guessing the file type.""" 126 return 'dummy.' + _guessextention(storefile)
127
128 -def _getname(storefile):
129 """returns the filename""" 130 if storefile is None: 131 raise ValueError("This method cannot magically produce a filename when given None as input.") 132 if not isinstance(storefile, basestring): 133 if not hasattr(storefile, "name"): 134 storefilename = _getdummyname(storefile) 135 else: 136 storefilename = storefile.name 137 else: 138 storefilename = storefile 139 return storefilename
140
141 -def getclass(storefile, ignore=None):
142 """Factory that returns the applicable class for the type of file presented. 143 Specify ignore to ignore some part at the back of the name (like .gz). """ 144 storefilename = _getname(storefile) 145 if ignore and storefilename.endswith(ignore): 146 storefilename = storefilename[:-len(ignore)] 147 root, ext = os.path.splitext(storefilename) 148 ext = ext[len(os.path.extsep):].lower() 149 decomp = None 150 if ext in decompressclass: 151 decomp = ext 152 root, ext = os.path.splitext(root) 153 ext = ext[len(os.path.extsep):].lower() 154 if ext in hiddenclasses: 155 guesserfn = hiddenclasses[ext] 156 if decomp: 157 ext = guesserfn(decompressclass[decomp](storefile)) 158 else: 159 ext = guesserfn(storefile) 160 try: 161 storeclass = classes[ext] 162 except KeyError: 163 raise ValueError("Unknown filetype (%s)" % storefilename) 164 return storeclass
165
166 -def getobject(storefile, ignore=None):
167 """Factory that returns a usable object for the type of file presented. 168 169 @type storefile: file or str 170 @param storefile: File object or file name. 171 172 Specify ignore to ignore some part at the back of the name (like .gz). 173 """ 174 175 if isinstance(storefile, base.TranslationStore): 176 return storefile 177 if isinstance(storefile, basestring): 178 if os.path.isdir(storefile) or storefile.endswith(os.path.sep): 179 from translate.storage import directory 180 return directory.Directory(storefile) 181 storefilename = _getname(storefile) 182 storeclass = getclass(storefile, ignore) 183 if os.path.exists(storefilename) or not getattr(storefile, "closed", True): 184 name, ext = os.path.splitext(storefilename) 185 ext = ext[len(os.path.extsep):].lower() 186 if ext in decompressclass: 187 storefile = decompressclass[ext](storefilename) 188 store = storeclass.parsefile(storefile) 189 else: 190 store = storeclass() 191 return store
192
193 -def supported_files():
194 """Returns data about all supported files 195 196 @return: list of type that include (name, extensions, mimetypes) 197 @rtype: list 198 """ 199 200 supported = [] 201 processed = [] 202 for supported_class in classes.itervalues(): 203 name = getattr(supported_class, "Name", None) 204 if name is None or name in processed: 205 continue 206 processed.append(name) 207 extensions = getattr(supported_class, "Extensions", None) 208 mimetypes = getattr(supported_class, "Mimetypes", None) 209 supported.extend([(name, extensions, mimetypes)]) 210 return supported
211