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 omegat 
 37  from translate.storage import po 
 38  from translate.storage import qm 
 39  from translate.storage import wordfast 
 40  #Let's try to import the XML formats carefully. They might fail if the user 
 41  #doesn't have lxml installed. Let's try to continue gracefully, but print an  
 42  #informative warning. 
 43  try: 
 44      #Although poxliff is unused in this module, it is referenced in test_factory 
 45      from translate.storage import poxliff 
 46      from translate.storage import qph 
 47      from translate.storage import tbx 
 48      from translate.storage import tmx 
 49      from translate.storage import ts2 as ts 
 50      from translate.storage import xliff 
 51      support_xml = True 
 52  except ImportError, e: 
 53      print >> sys.stderr, str(e) 
 54      support_xml = False 
 55   
 56   
 57  #TODO: Monolingual formats (with template?) 
 58   
 59  classes = { 
 60             "csv": csvl10n.csvfile,  
 61             "tab": omegat.OmegaTFileTab, "utf8": omegat.OmegaTFile, 
 62             "po": po.pofile, "pot": po.pofile,  
 63             "mo": mo.mofile, "gmo": mo.mofile,  
 64             "qm": qm.qmfile,  
 65             "_wftm": wordfast.WordfastTMFile, 
 66            } 
 67  """Dictionary of file extensions and their associated class.   
 68   
 69  _ext is a pseudo extension, that is their is no real extension by that name.""" 
 70   
 71  if support_xml: 
 72      classes.update({ 
 73             "qph": qph.QphFile, 
 74             "tbx": tbx.tbxfile, 
 75             "tmx": tmx.tmxfile,  
 76             "ts": ts.tsfile, 
 77             "xliff": xliff.xlifffile, "xlf": xliff.xlifffile, 
 78      }) 
 79   
 80  decompressclass = { 
 81      'gz': GzipFile, 
 82  } 
 83  if BZ2File: 
 84      decompressclass['bz2'] = BZ2File 
 85   
86 -def _examine_txt(storefile):
87 """Determine the true filetype for a .txt file""" 88 if isinstance(storefile, basestring) and os.path.exists(storefile): 89 storefile = open(storefile) 90 try: 91 start = storefile.read(600).strip() 92 except AttributeError: 93 raise ValueError("Need to read object to determine type") 94 # Some encoding magic for Wordfast 95 if wordfast.TAB_UTF16 in start.split("\n")[0]: 96 encoding = 'utf-16' 97 else: 98 encoding = 'iso-8859-1' 99 start = start.decode(encoding).encode('utf-8') 100 if '%Wordfast TM' in start: 101 pseudo_extension = '_wftm' 102 else: 103 raise ValueError("Failed to guess file type.") 104 storefile.seek(0) 105 return pseudo_extension
106 107 hiddenclasses = {"txt": _examine_txt} 108
109 -def _guessextention(storefile):
110 """Guesses the type of a file object by looking at the first few characters. 111 The return value is a file extention .""" 112 start = storefile.read(300).strip() 113 if '<xliff ' in start: 114 extention = 'xlf' 115 elif 'msgid "' in start: 116 extention = 'po' 117 elif '%Wordfast TM' in start: 118 extention = 'txt' 119 elif '<!DOCTYPE TS>' in start: 120 extention = 'ts' 121 elif '<tmx ' in start: 122 extention = 'tmx' 123 else: 124 raise ValueError("Failed to guess file type.") 125 storefile.seek(0) 126 return extention
127
128 -def _getdummyname(storefile):
129 """Provides a dummy name for a file object without a name attribute, by guessing the file type.""" 130 return 'dummy.' + _guessextention(storefile)
131
132 -def _getname(storefile):
133 """returns the filename""" 134 if storefile is None: 135 raise ValueError("This method cannot magically produce a filename when given None as input.") 136 if not isinstance(storefile, basestring): 137 if not hasattr(storefile, "name"): 138 storefilename = _getdummyname(storefile) 139 else: 140 storefilename = storefile.name 141 else: 142 storefilename = storefile 143 return storefilename
144
145 -def getclass(storefile, ignore=None, classes=classes, hiddenclasses=hiddenclasses):
146 """Factory that returns the applicable class for the type of file presented. 147 Specify ignore to ignore some part at the back of the name (like .gz). """ 148 storefilename = _getname(storefile) 149 if ignore and storefilename.endswith(ignore): 150 storefilename = storefilename[:-len(ignore)] 151 root, ext = os.path.splitext(storefilename) 152 ext = ext[len(os.path.extsep):].lower() 153 decomp = None 154 if ext in decompressclass: 155 decomp = ext 156 root, ext = os.path.splitext(root) 157 ext = ext[len(os.path.extsep):].lower() 158 if ext in hiddenclasses: 159 guesserfn = hiddenclasses[ext] 160 if decomp: 161 ext = guesserfn(decompressclass[decomp](storefile)) 162 else: 163 ext = guesserfn(storefile) 164 try: 165 storeclass = classes[ext] 166 except KeyError: 167 raise ValueError("Unknown filetype (%s)" % storefilename) 168 return storeclass
169
170 -def getobject(storefile, ignore=None, classes=classes, hiddenclasses=hiddenclasses):
171 """Factory that returns a usable object for the type of file presented. 172 173 @type storefile: file or str 174 @param storefile: File object or file name. 175 176 Specify ignore to ignore some part at the back of the name (like .gz). 177 """ 178 179 if isinstance(storefile, base.TranslationStore): 180 return storefile 181 if isinstance(storefile, basestring): 182 if os.path.isdir(storefile) or storefile.endswith(os.path.sep): 183 from translate.storage import directory 184 return directory.Directory(storefile) 185 storefilename = _getname(storefile) 186 storeclass = getclass(storefile, ignore, classes=classes, hiddenclasses=hiddenclasses) 187 if os.path.exists(storefilename) or not getattr(storefile, "closed", True): 188 name, ext = os.path.splitext(storefilename) 189 ext = ext[len(os.path.extsep):].lower() 190 if ext in decompressclass: 191 storefile = decompressclass[ext](storefilename) 192 store = storeclass.parsefile(storefile) 193 else: 194 store = storeclass() 195 store.filename = storefilename 196 return store
197
198 -def supported_files():
199 """Returns data about all supported files 200 201 @return: list of type that include (name, extensions, mimetypes) 202 @rtype: list 203 """ 204 205 supported = {} 206 for supported_class in classes.itervalues(): 207 name = getattr(supported_class, "Name", None) 208 if name is None: 209 continue 210 extensions = getattr(supported_class, "Extensions", None) 211 mimetypes = getattr(supported_class, "Mimetypes", None) 212 if not supported.has_key(name): 213 supported[name] = (extensions, mimetypes) 214 else: 215 supported[name][0].extend(extensions) 216 supported[name][1].extend(mimetypes) 217 return [(name, ext_mime[0], ext_mime[1]) for name, ext_mime in supported.iteritems()]
218