fnds Posted May 15, 2008 Report Share Posted May 15, 2008 Antes que comecem a dizer que scripts que façam isto não faltam, eu fiz isto antes de ir ver se existia, só depois é que reparei que a biblioteca padrão até já tem... Este script permite traduzir strings dos ficheiros mo, nos dois sentidos, faz cache (dois tipos) e permite exportar. #!/usr/bin/python # -*- coding: utf-8 -*- """Coded by Fabio André Domingues (fnds) ___________________________________________________________________________ python GetText - It can read MO files and use them for translating strings. Classes: GetText(mo_file, cache_type=NONE). Constants: ERROR = 'GetTextError'; NONE = None; ALL = 1; ALL_PROGRESSIVE = 2; INDEXS = 3; VALUES = 4.""" from sys import exit as _sys_exit from struct import unpack as _unpack ERROR = 'GetTextError' NONE = None ALL = 1 ALL_PROGRESSIVE = 2 INDEXS = 3 VALUES = 4 class GetText(): """ __init__(mo_file, cache_type=NONE): mo_file - path to mo file; cache_type - type of cache mechanism: NONE - no cache; ALL - all strings are cached, mo file is closed; ALL_PROGRESSIVE - strings are cached when used. get_value(index_string) - return de value of index_string. get_index(value_string) - return de index os value_string. export(what): what: ALL - return a dict {index: value} with all strings; INDEXS - return a tuple (index1, index2) with all indexs; VALUES - return a tuple (value1, value2) with all values;""" def __init__(self, mo_file, cache_type=None): self._file = open(mo_file, 'rb') self._byte_order = '' self._cache_type = cache_type #Check file and define byte order # < - little-endian # > - big-endian magic = self._read_int() if magic == 2500072158: self._byte_order = '<' elif magic == 3725722773: self._byte_order = '>' else: raise ERROR, '"%s" is not MO file.' % file #File info revision = self._read_int() self.total = self._read_int() indexs_pos = self._read_int() values_pos = self._read_int() #Get table of indexs self._file.seek(indexs_pos) self._table_indexs = self._read_int_tuple(self.total*2) #Get table of values self._file.seek(values_pos) self._table_values = self._read_int_tuple(self.total*2) #Check cache_type if self._cache_type == NONE: self._cache_contents = None elif self._cache_type == ALL: self._cache_contents = self._extract_all() self._file.close()#Cache all -> close file elif self._cache_type == ALL_PROGRESSIVE: self._cache_contents = {} else: raise ERROR, 'Incorrect value of cache_type. [NONE, ALL, ALL_PROGRESSIVE]' #### Nucleo Duro #### #Read data from mo_file def _file_read(self, bytes): data = '' while bytes > 0: chunk = self._file.read(bytes) data += chunk bytes -= len(chunk) return data #Unpack one structure, return string def _read_int(self): return _unpack(self._byte_order+'L', self._file_read(4))[0] #Unpack many structure, return tuple def _read_int_tuple(self, count): return _unpack(self._byte_order+'L'*count, self._file_read(4*count)) #Extract all indexs/values from file, return dict {index: value} def _extract_all(self): all = {} for i in range(self.total): self._file.seek(self._table_indexs[i*2+1]) index = self._file_read(self._table_indexs[i*2]) self._file.seek(self._table_values[i*2+1]) all[index] = self._file_read(self._table_values[i*2]) return all #Extract all indexs from file, return tuple (index1, index2) def _extract_indexs(self): indexs = () for i in range(self.total): self._file.seek(self._table_indexs[i*2+1]) indexs += self._file_read(self._table_indexs[i*2]), return indexs #Extract all values from file, return tuple (value1, value2) def _extract_values(self): values = () for i in range(self.total): self._file.seek(self._table_values[i*2+1]) values += self._file_read(self._table_values[i*2]), return values #### fim Nucleo Duro #### #Return de value of index def get_value(self, index_string): if self._cache_type == ALL:#Cache all, get cache item if index_string in self._cache_contents: return self._cache_contents[index_string] else: raise ERROR, 'Index "%s" don\'t have value.' % index_string elif self._cache_type == ALL_PROGRESSIVE:#Cache progressive if index_string in self._cache_contents:#If item in cache get it return self._cache_contents[index_string] else:#else get from file and put in cache for i in range(self.total): self._file.seek(self._table_indexs[i*2+1]) index = self._file_read(self._table_indexs[i*2]) if index_string == index: self._file.seek(self._table_values[i*2+1]) self._cache_contents[index_string] = self._file_read(self._table_values[i*2]) return self._cache_contents[index_string] raise ERROR, 'Index "%s" don\'t have value.' % index_string else:#Not cache, get item from file for i in range(self.total): self._file.seek(self._table_indexs[i*2+1]) index = self._file_read(self._table_indexs[i*2]) if index_string == index: self._file.seek(self._table_values[i*2+1]) return self._file_read(self._table_values[i*2]) raise ERROR, 'Index "%s" don\'t have value.' % index_string #The same of get_value but return index of value def get_index(self, value_string): if self._cache_type == ALL: if value_string in self._cache_contents.values(): for index, value in self._cache_contents.iteritems(): if value == value_string: return index else: raise ERROR, 'Value "%s" don\'t have index.' % value_string elif self._cache_type == ALL_PROGRESSIVE: if value_string in self._cache_contents.values(): for index, value in self._cache_contents.iteritems(): if value == value_string: return index else: for i in range(self.total): self._file.seek(self._table_values[i*2+1]) value = self._file_read(self._table_values[i*2]) if value_string == value: self._file.seek(self._table_indexs[i*2+1]) index = self._file_read(self._table_indexs[i*2]) self._cache_contents[index] = value return index raise ERROR, 'Value "%s" don\'t have index.' % value_string else: for i in range(self.total): self._file.seek(self._table_values[i*2+1]) value = self._file_read(self._table_values[i*2]) if value_string == value: self._file.seek(self._table_indexs[i*2+1]) return self._file_read(self._table_indexs[i*2]) raise ERROR, 'Value "%s" don\'t have index.' % value_string #Export data, use cache if is ALL def export(self, what=ALL): if what == ALL: if self._cache_type == ALL: return self._cache_contents else: return self._extract_all() elif what == INDEXS: if self._cache_type == ALL: return self._cache_contents.keys() else: return self._extract_indexs() elif what == VALUES: if self._cache_type == ALL: return self._cache_contents.values() else: return self._extract_values() else: raise ERROR, 'Incorrect value of what. [ALL, INDEXS, VALUES]' Qualquer coisa, sugestão, critica que possa melhorar este código digam, porque sinseramente eu acho que isto está bom. 😁 Link to comment Share on other sites More sharing options...
fnds Posted May 15, 2008 Author Report Share Posted May 15, 2008 Exemplo de uso: from GetText import * _ = GetText('file.mo', ALL).get_value print _('Hello') Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now