def load_config(self): """Load terminology backend config from default location""" self.config = {} self.config.update(self.default_config) config_file = os.path.join(pan_app.get_config_dir(), "terminology.ini") self.config.update(pan_app.load_config(config_file, self.internal_name))
def load_config(self): """Load plugin config from default location.""" self.config = {} self.config.update(self.default_config) config_file = os.path.join(pan_app.get_config_dir(), "plugins.ini") self.config.update(pan_app.load_config(config_file, self.internal_name))
def __init__(self, internal_name, controller): self.controller = controller self.internal_name = internal_name self.configure_func = self.configure self.urldata_file = path.join(pan_app.get_config_dir(), "weblookup.ini") self._load_urldata()
def _on_quit(self, main_controller): pan_app.settings.language['sourcelang'] = self.source_lang.code pan_app.settings.language['targetlang'] = self.target_lang.code if not self.new_langs: return langs = {} filename = os.path.join(pan_app.get_config_dir(), 'langs.ini') if os.path.isfile(filename): langs = pan_app.load_config(filename) newlangdict = {} for code in self.new_langs: newlangdict[code] = {} newlangdict[code]['name'] = LanguageModel.languages[code][0] newlangdict[code]['nplurals'] = LanguageModel.languages[code][1] newlangdict[code]['plural'] = LanguageModel.languages[code][2] langs.update(newlangdict) pan_app.save_config(filename, langs)
def _init_langs(self): try: self._source_lang = LanguageModel( pan_app.settings.language['sourcelang']) except Exception: self._source_lang = None try: self._target_lang = LanguageModel( pan_app.settings.language['targetlang']) except Exception: self._target_lang = None # Load previously-saved (new) languages filename = os.path.join(pan_app.get_config_dir(), 'langs.ini') if os.path.isfile(filename): languages = pan_app.load_config(filename) for code in languages: languages[code] = (languages[code]['name'], int(languages[code]['nplurals']), languages[code]['plural']) LanguageModel.languages.update(languages)
def _init_langs(self): try: self._source_lang = LanguageModel(pan_app.settings.language['sourcelang']) except Exception: self._source_lang = None try: self._target_lang = LanguageModel(pan_app.settings.language['targetlang']) except Exception: self._target_lang = None # Load previously-saved (new) languages filename = os.path.join(pan_app.get_config_dir(), 'langs.ini') if os.path.isfile(filename): languages = pan_app.load_config(filename) for code in languages: languages[code] = ( languages[code]['name'], int(languages[code]['nplurals']), languages[code]['plural'] ) LanguageModel.languages.update(languages)
class TerminologyModel(BaseTerminologyModel): """A terminology back-end to access the Translate.org.za-managed terminology.""" __gtype_name__ = 'AutoTermTerminology' display_name = _('Localization Terminology') description = _('Selected localization terminology') _l10n_URL = 'http://terminology.locamotion.org/l10n/%(srclang)s/%(tgtlang)s' TERMDIR = os.path.join(pan_app.get_config_dir(), 'autoterm') # INITIALIZERS # def __init__(self, internal_name, controller): super(TerminologyModel, self).__init__(controller) self.internal_name = internal_name self.client = HTTPClient() self.client.set_virtaal_useragent() self.load_config() if not os.path.isdir(self.TERMDIR): os.mkdir(self.TERMDIR) self.main_controller = controller.main_controller self.term_controller = controller self.matcher = None self.init_matcher() lang_controller = self.main_controller.lang_controller self.source_lang = lang_controller.source_lang.code self.target_lang = lang_controller.target_lang.code self._connect_ids.append(( lang_controller.connect('source-lang-changed', self._on_lang_changed, 'source'), lang_controller )) self._connect_ids.append(( lang_controller.connect('target-lang-changed', self._on_lang_changed, 'target'), lang_controller )) self.update_terms() def init_matcher(self, filename=''): """ Initialize the matcher to be used by the C{TerminologyPlaceable} parser. """ if self.matcher in TerminologyPlaceable.matchers: TerminologyPlaceable.matchers.remove(self.matcher) if os.path.isfile(filename): logging.debug('Loading terminology from %s' % (filename)) self.store = factory.getobject(filename) else: logging.debug('Creating empty terminology store') self.store = TranslationStore() self.store.makeindex() self.matcher = terminologymatcher(self.store) TerminologyPlaceable.matchers.append(self.matcher) # ACCESSORS # def _get_curr_term_filename(self, srclang=None, tgtlang=None, ext=None): if srclang is None: srclang = self.source_lang if tgtlang is None: tgtlang = self.target_lang if not ext: ext = 'po' base = '%s__%s' % (srclang, tgtlang) for filename in os.listdir(self.TERMDIR): if filename.startswith(base): return filename return base + os.extsep + ext curr_term_filename = property(_get_curr_term_filename) # METHODS # def update_terms(self, srclang=None, tgtlang=None): """Update the terminology file for the given language or all if none specified.""" if srclang is None: srclang = self.source_lang if tgtlang is None: tgtlang = self.target_lang if srclang is None and tgtlang is None: # Update all files return if srclang is None or tgtlang is None: raise ValueError('Both srclang and tgtlang must be specified') if not self.is_update_needed(srclang, tgtlang): logging.debug('Skipping update for (%s, %s) language pair' % (srclang, tgtlang)) localfile = self._get_curr_term_filename(srclang, tgtlang) localfile = os.path.join(self.TERMDIR, localfile) self.init_matcher(localfile) return self._update_term_file(srclang, tgtlang) def is_update_needed(self, srclang, tgtlang): localfile = self._get_curr_term_filename(srclang, tgtlang) localfile = os.path.join(self.TERMDIR, localfile) if not os.path.isfile(localfile): return True stats = os.stat(localfile) from datetime import datetime return (time.mktime(datetime.now().timetuple()) - stats.st_mtime) > THREE_DAYS def _check_for_update(self, srclang, tgtlang): localfile = self._get_curr_term_filename(srclang, tgtlang) localfile = os.path.join(self.TERMDIR, localfile) etag = None if os.path.isfile(localfile) and localfile in self.config: etag = self.config[os.path.abspath(localfile)] url = self._l10n_URL % {'srclang': srclang, 'tgtlang': tgtlang} if not os.path.isfile(localfile): localfile = None callback = lambda *args: self._process_header(localfile=localfile, *args) if logging.root.level != logging.DEBUG: self.client.get(url, callback, etag) else: def error_log(request, result): logging.debug('Could not get %s: status %d' % (url, request.status)) self.client.get(url, callback, etag, error_callback=error_log) def _get_ext_from_url(self, url): from urlparse import urlparse parsed = urlparse(url) #dir, filename = os.path.split(parsed.path) #rewritten for compatibility with Python 2.4: dir, filename = os.path.split(parsed[2]) if not filename or '.' not in filename: return None ext = filename.split('.')[-1] if not ext: ext = None return ext def _get_ext_from_store_guess(self, content): from StringIO import StringIO from translate.storage.factory import _guessextention s = StringIO(content) try: return _guessextention(s) except ValueError: pass return None def _process_header(self, request, result, localfile=None): if request.status == 304: logging.debug('ETag matches for file %s :)' % (localfile)) elif request.status == 200: if not localfile: ext = self._get_ext_from_url(request.get_effective_url()) if ext is None: ext = self._get_ext_from_store_guess(result) if ext is None: logging.debug('Unable to determine extension for store. Defaulting to "po".') ext = 'po' localfile = self._get_curr_term_filename(ext=ext) localfile = os.path.join(self.TERMDIR, localfile) logging.debug('Saving to %s' % (localfile)) open(localfile, 'w').write(result) # Find ETag header and save the value headers = request.result_headers.getvalue().splitlines() etag = '' etagline = [l for l in headers if l.lower().startswith('etag:')] if etagline: etag = etagline[0][7:-1] self.config[os.path.abspath(localfile)] = etag else: logging.debug('Unhandled status code: %d' % (request.status)) localfile = '' if os.path.isfile(localfile): # Update mtime os.utime(localfile, None) self.init_matcher(localfile) def _update_term_file(self, srclang, tgtlang): """Update the terminology file for the given languages.""" self.init_matcher() # Make sure that the matcher is empty until we have an update filename = self._get_curr_term_filename(srclang, tgtlang) localfile = os.path.join(self.TERMDIR, filename) self._check_for_update(srclang, tgtlang) # SIGNAL HANDLERS # def _on_lang_changed(self, lang_controller, lang, which): setattr(self, '%s_lang' % (which), lang) self.update_terms(self.source_lang, self.target_lang)
def save_config(self): """Save terminology backend config to default location""" config_file = os.path.join(pan_app.get_config_dir(), "terminology.ini") pan_app.save_config(config_file, self.config, self.internal_name)
class PluginController(BaseController): """This controller is responsible for all plug-in management.""" __gtype_name__ = 'PluginController' __gsignals__ = { 'plugin-enabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), 'plugin-disabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), } # The following class variables are set for the main plug-in controller. # To use this class to manage any other plug-ins, these will (most likely) have to be changed. PLUGIN_CLASSNAME = 'Plugin' """The name of the class that will be instantiated from the plug-in module.""" PLUGIN_CLASS_INFO_ATTRIBS = ['description', 'display_name', 'version'] """Attributes of the plug-in class that contain info about it. Should contain PLUGIN_NAME_ATTRIB.""" PLUGIN_DIRS = [ os.path.join(pan_app.get_config_dir(), u'virtaal_plugins'), os.path.join( os.path.dirname(__file__).decode(sys.getfilesystemencoding()), u'..', u'plugins') ] """The directories to search for plug-in names.""" PLUGIN_INTERFACE = BasePlugin """The interface class that the plug-in class must inherit from.""" PLUGIN_MODULES = ['virtaal_plugins', 'virtaal.plugins'] """The module name to import the plugin from. This is prepended to the plug-in's name as found by C{_find_plugin_names()} and passed to C{__import__()}.""" PLUGIN_NAME_ATTRIB = 'display_name' """The attribute of a plug-in that contains its name.""" # INITIALIZERS # def __init__(self, controller, classname=None): GObjectWrapper.__init__(self) self.controller = controller if classname: self.PLUGIN_CLASSNAME = classname else: # controller is maincontroller controller.plugin_controller = self self.plugins = {} self.pluginmodules = {} if os.name == 'nt': self.PLUGIN_DIRS.insert( 0, os.path.join(pan_app.main_dir, u'virtaal_plugins')) if 'RESOURCEPATH' in os.environ: self.PLUGIN_DIRS.insert( 0, os.path.join( os.environ['RESOURCEPATH'].decode( sys.getfilesystemencoding()), u'virtaal_plugins')) # METHODS # def disable_plugin(self, name): """Destroy the plug-in with the given name.""" logging.debug('Disabling plugin: %s' % (name)) if name in self.plugins: self.emit('plugin-disabled', self.plugins[name]) self.plugins[name].destroy() del self.plugins[name] if name in self.pluginmodules: del self.pluginmodules[name] def enable_plugin(self, name): """Load the plug-in with the given name and instantiate it.""" if name in self.plugins: return None try: plugin_class = self._get_plugin_class(name) try: self.plugins[name] = plugin_class(name, self.controller) except PluginUnsupported, pu: logging.info(pu.message) return None self.emit('plugin-enabled', self.plugins[name]) logging.info( ' - ' + getattr(self.plugins[name], self.PLUGIN_NAME_ATTRIB, name)) return self.plugins[name] except Exception, e: # the name is unicode which can trigger encoding issues in the # logging module, so let's encode it now already logging.exception('Failed to load plugin "%s"\n%s' % (name.encode('utf-8'), e))
from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT, idle_add from virtaal.common import pan_app, GObjectWrapper from basecontroller import BaseController from baseplugin import PluginUnsupported, BasePlugin if os.name == 'nt': sys.path.insert(0, pan_app.main_dir.encode(sys.getfilesystemencoding())) if 'RESOURCEPATH' in os.environ: sys.path.insert(0, os.path.join(os.environ['RESOURCEPATH'])) # The following line allows us to import user plug-ins from ~/.virtaal/virtaal_plugins # (see PluginController.PLUGIN_MODULES) sys.path.insert(0, pan_app.get_config_dir().encode(sys.getfilesystemencoding())) class PluginController(BaseController): """This controller is responsible for all plug-in management.""" __gtype_name__ = 'PluginController' __gsignals__ = { 'plugin-enabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), 'plugin-disabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), } # The following class variables are set for the main plug-in controller. # To use this class to manage any other plug-ins, these will (most likely) have to be changed. PLUGIN_CLASSNAME = 'Plugin' """The name of the class that will be instantiated from the plug-in module."""
import sys from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT, idle_add from virtaal.common import pan_app, GObjectWrapper from basecontroller import BaseController from baseplugin import BasePlugin if os.name == 'nt': sys.path.insert(0, pan_app.main_dir) if 'RESOURCEPATH' in os.environ: sys.path.insert(0, os.path.join(os.environ['RESOURCEPATH'])) # The following line allows us to import user plug-ins from ~/.virtaal/virtaal_plugins # (see PluginController.PLUGIN_MODULES) sys.path.insert(0, pan_app.get_config_dir()) class PluginController(BaseController): """This controller is responsible for all plug-in management.""" __gtype_name__ = 'PluginController' __gsignals__ = { 'plugin-enabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), 'plugin-disabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT, )), } # The following class variables are set for the main plug-in controller. # To use this class to manage any other plug-ins, these will (most likely) have to be changed. PLUGIN_CLASSNAME = 'Plugin' """The name of the class that will be instantiated from the plug-in module."""
def load_config(self): """load TM backend config from default location""" self.config = {} self.config.update(self.default_config) config_file = os.path.join(pan_app.get_config_dir(), "tm.ini") self.config.update(pan_app.load_config(config_file, self.internal_name))
class Plugin(BasePlugin): description = _( 'Migrate settings from KBabel, Lokalize and/or Poedit to Virtaal.') display_name = _('Migration Assistant') version = 0.1 default_config = {"tmdb": path.join(pan_app.get_config_dir(), "tm.db")} def __init__(self, internal_name, main_controller): self.internal_name = internal_name self.main_controller = main_controller self.load_config() self._init_plugin() def _init_plugin(self): message = _( 'Should Virtaal try to import settings and data from other applications?' ) must_migrate = self.main_controller.show_prompt( _('Import data from other applications?'), message) if not must_migrate: logging.debug('Migration not done due to user choice') else: # We'll store the tm here: self.tmdb = tmdb.TMDB(self.config["tmdb"]) # We actually need source, target, context, targetlanguage self.migrated = [] if sys.platform == "darwin": self.poedit_dir = path.expanduser('~/Library/Preferences') else: self.poedit_dir = path.expanduser('~/.poedit') #TODO: check if we can do better than hardcoding the kbabel location #this path is specified in ~/.kde/config/kbabel.defaultproject and kbabeldictrc self.kbabel_dir = path.expanduser( '~/.kde/share/apps/kbabeldict/dbsearchengine') self.lokalize_rc = path.expanduser( '~/.kde/share/config/lokalizerc') self.lokalize_tm_dir = path.expanduser( '~/.kde/share/apps/lokalize/') self.poedit_settings_import() self.poedit_tm_import() self.kbabel_tm_import() self.lokalize_settings_import() self.lokalize_tm_import() if self.migrated: message = _('Migration was successfully completed') + '\n\n' message += _('The following items were migrated:') + '\n\n' message += u"\n".join( [u" • %s" % item for item in self.migrated]) # (we can mark this ^^^ for translation if somebody asks) self.main_controller.show_info(_('Migration completed'), message) else: message = _( "Virtaal was not able to migrate any settings or data") self.main_controller.show_info(_('Nothing migrated'), message) logging.debug('Migration plugin executed') pan_app.settings.plugin_state[self.internal_name] = "disabled" def poedit_settings_import(self): """Attempt to import the settings from Poedit.""" if sys.platform == 'darwin': config_filename = path.join(self.poedit_dir, 'net.poedit.Poedit.cfg') else: config_filename = path.join(self.poedit_dir, 'config') get_thing = None if not path.exists(config_filename): try: import _winreg except Exception, e: return def get_thing(section, item): key = None try: key = _winreg.OpenKey( _winreg.HKEY_CURRENT_USER, r"Software\Vaclav Slavik\Poedit\%s" % section) except WindowsError: return data = None try: # This is very inefficient, but who cares? for i in range(100): name, data, type = _winreg.EnumValue(key, i) if name == item: break except EnvironmentError, e: pass except Exception, e: logging.exception("Error obtaining from registry: %s, %s", section, item) return data
from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT, idle_add from virtaal.common import pan_app, GObjectWrapper from basecontroller import BaseController from baseplugin import BasePlugin if os.name == 'nt': sys.path.insert(0, pan_app.main_dir) if 'RESOURCEPATH' in os.environ: sys.path.insert(0, os.path.join(os.environ['RESOURCEPATH'])) # The following line allows us to import user plug-ins from ~/.virtaal/virtaal_plugins # (see PluginController.PLUGIN_MODULES) sys.path.insert(0, pan_app.get_config_dir()) class PluginController(BaseController): """This controller is responsible for all plug-in management.""" __gtype_name__ = 'PluginController' __gsignals__ = { 'plugin-enabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT,)), 'plugin-disabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT,)), } # The following class variables are set for the main plug-in controller. # To use this class to manage any other plug-ins, these will (most likely) have to be changed. PLUGIN_CLASSNAME = 'Plugin' """The name of the class that will be instantiated from the plug-in module.""" PLUGIN_CLASS_INFO_ATTRIBS = ['description', 'display_name', 'version']
def save_config(self): """Save plugin config to default location.""" config_file = os.path.join(pan_app.get_config_dir(), "plugins.ini") pan_app.save_config(config_file, self.config, self.internal_name)
from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT, idle_add from virtaal.common import pan_app, GObjectWrapper from basecontroller import BaseController from baseplugin import PluginUnsupported, BasePlugin if os.name == 'nt': sys.path.insert(0, pan_app.main_dir.encode(sys.getfilesystemencoding())) if 'RESOURCEPATH' in os.environ: sys.path.insert(0, os.path.join(os.environ['RESOURCEPATH'])) # The following line allows us to import user plug-ins from ~/.virtaal/virtaal_plugins # (see PluginController.PLUGIN_MODULES) sys.path.insert(0, pan_app.get_config_dir().encode(sys.getfilesystemencoding())) class PluginController(BaseController): """This controller is responsible for all plug-in management.""" __gtype_name__ = 'PluginController' __gsignals__ = { 'plugin-enabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT,)), 'plugin-disabled': (SIGNAL_RUN_FIRST, None, (TYPE_PYOBJECT,)), } # The following class variables are set for the main plug-in controller. # To use this class to manage any other plug-ins, these will (most likely) have to be changed. PLUGIN_CLASSNAME = 'Plugin' """The name of the class that will be instantiated from the plug-in module.""" PLUGIN_CLASS_INFO_ATTRIBS = ['description', 'display_name', 'version']
class TerminologyModel(BaseTerminologyModel): """ Terminology model that loads terminology from a PO file on the local filesystem. """ __gtype_name__ = 'LocalFileTerminologyModel' display_name = _('Local Files') description = _('Local terminology files') default_config = { 'extendfile': os.path.join(pan_app.get_config_dir(), 'terminology.po'), 'files': '' } # INITIALIZERS # def __init__(self, internal_name, controller): super(TerminologyModel, self).__init__(controller) self.matcher = None self.internal_name = internal_name self.stores = [] self.load_config() self.load_files() self.view = LocalFileView(self) # METHODS # def destroy(self): self.view.destroy() self.save_config() super(TerminologyModel, self).destroy() if self.matcher in TerminologyPlaceable.matchers: TerminologyPlaceable.matchers.remove(self.matcher) def get_duplicates(self, src_text, tgt_text): base_src_text = src_text.strip() base_tgt_text = tgt_text.strip() units = [] for store in self.stores: for unit in store.units: if unit.source.strip() == base_src_text and \ unit.target.strip() == base_tgt_text: return True return False def get_extend_store(self): extendfile = self.config['extendfile'] for store in self.stores: if os.path.abspath(getattr(store, 'filename', '')) == os.path.abspath(extendfile): return store return None def get_store_for_filename(self, filename): for store in self.stores: if os.path.abspath(getattr(store, 'filename', '')) == os.path.abspath(filename): return store return None def get_units_with_source(self, src_text): stripped_src_text = src_text.strip().lower() units = [] for store in self.stores: for unit in store.units: if unit.source.strip().lower() == stripped_src_text: units.append(unit) return units def load_config(self): super(TerminologyModel, self).load_config() conffiles = [] for filename in self.config['files'].split(','): if os.path.exists(filename): conffiles.append(filename) self.config['files'] = conffiles if not os.path.exists( self.config['extendfile']) and len(self.config['files']) > 0: self.config['extendfile'] = self.config['files'][0] if not os.path.exists(self.config['extendfile']): self.config['extendfile'] = self.default_config['extendfile'] if not self.config['extendfile'] in self.config['files']: self.config['files'].append(self.config['extendfile']) def load_files(self): if self.matcher in TerminologyPlaceable.matchers: TerminologyPlaceable.matchers.remove(self.matcher) self.stores = [] for filename in self.config['files']: if not filename: continue if not os.path.isfile(filename): logging.debug('Not a file: "%s"' % (filename)) self.stores.append(factory.getobject(filename)) self.matcher = terminologymatcher(self.stores) TerminologyPlaceable.matchers.append(self.matcher)
def save_config(self): """save TM backend config to default location""" config_file = os.path.join(pan_app.get_config_dir(), "tm.ini") pan_app.save_config(config_file, self.config, self.internal_name)
class TMModel(remotetm.TMModel): """This is the translation memory model.""" __gtype_name__ = 'LocalTMModel' display_name = _('Local Translation Memory') description = _('Previous translations you have made') #l10n: Try to keep this as short as possible. shortname = _('Local TM') default_config = { "tmserver_bind": "localhost", "tmserver_port": "55555", "tmdb": os.path.join(pan_app.get_config_dir(), u"tm.db") } # INITIALIZERS # def __init__(self, internal_name, controller): self.internal_name = internal_name self.load_config() # test if port specified in config is free self.config["tmserver_port"] = int(self.config["tmserver_port"]) if test_port(self.config["tmserver_bind"], self.config["tmserver_port"]): port = self.config["tmserver_port"] else: port = find_free_port(self.config["tmserver_bind"], 49152, 65535) if os.name == "nt": executable = os.path.abspath( os.path.join(pan_app.main_dir, u"tmserver.exe")) else: executable = u"tmserver" command = [ executable.encode(sys.getfilesystemencoding()), "-b", self.config["tmserver_bind"], "-p", str(port), "-d", self.config["tmdb"].encode(sys.getfilesystemencoding()), "--min-similarity=%d" % controller.min_quality, "--max-candidates=%d" % controller.max_matches, ] if pan_app.DEBUG: command.append("--debug") logging.debug("launching tmserver with command %s" % " ".join(command)) try: import subprocess from virtaal.support import tmclient self.tmserver = subprocess.Popen(command) url = "http://%s:%d/tmserver" % (self.config["tmserver_bind"], port) self.tmclient = tmclient.TMClient(url) except OSError, e: message = "Failed to start TM server: %s" % str(e) logging.exception('Failed to start TM server') raise # Do not use super() here, as remotetm.TMModel does a bit more than we # want in this case. BaseTMModel.__init__(self, controller) self._connect_ids.append( (self.controller.main_controller.store_controller.connect( "store-saved", self.push_store), self.controller.main_controller.store_controller))