|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2008-2016 Mir Calculate. http://www.calculate-linux.org
|
|
|
#
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
# you may not use this file except in compliance with the License.
|
|
|
# You may obtain a copy of the License at
|
|
|
#
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
|
#
|
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
|
|
|
from os import path
|
|
|
import os
|
|
|
from calculate.lib.datavars import ReadonlyVariable
|
|
|
from calculate.lib.utils.common import (getValueFromCmdLine,
|
|
|
getValueFromConfig, CmdlineParams)
|
|
|
from collections import OrderedDict
|
|
|
|
|
|
import sys
|
|
|
from calculate.lib.cl_lang import setLocalTranslate, getLazyLocalTranslate
|
|
|
|
|
|
_ = lambda x: x
|
|
|
setLocalTranslate('cl_lib3', sys.modules[__name__])
|
|
|
|
|
|
__ = getLazyLocalTranslate(_)
|
|
|
|
|
|
|
|
|
class Locale(object):
|
|
|
# http://www.localeplanet.com/icu/
|
|
|
langData = OrderedDict([
|
|
|
('be_BY', {
|
|
|
'name': 'Беларуская (Беларусь)',
|
|
|
'locale': 'be_BY.UTF-8',
|
|
|
'keymap': 'by',
|
|
|
'timezone': 'Europe/Minsk',
|
|
|
'dumpkeys_charset': 'koi8-u',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,by',
|
|
|
'language': 'be',
|
|
|
}),
|
|
|
('bg_BG', {
|
|
|
'name': 'Български (България)',
|
|
|
'locale': 'bg_BG.UTF-8',
|
|
|
'keymap': 'bg_bds-utf8',
|
|
|
'dumpkeys_charset': '',
|
|
|
'timezone': 'Europe/Sofia',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,bg',
|
|
|
'language': 'bg',
|
|
|
}),
|
|
|
('bs_BA', {
|
|
|
'name': 'Bosanski (Bosna i Hercegovina)',
|
|
|
'locale': 'bs_BA.UTF-8',
|
|
|
'keymap': 'slovene',
|
|
|
'timezone': 'Europe/Sarajevo',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'ba',
|
|
|
'language': 'bs',
|
|
|
}),
|
|
|
('cs_CZ', {
|
|
|
'name': 'Čeština (Česká republika)',
|
|
|
'locale': 'cs_CZ.UTF-8',
|
|
|
'keymap': 'cz',
|
|
|
'timezone': 'Europe/Prague',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'cz',
|
|
|
'language': 'cs',
|
|
|
}),
|
|
|
('da_DK', {
|
|
|
'name': 'Dansk (Danmark)',
|
|
|
'locale': 'da_DK.UTF-8',
|
|
|
'keymap': 'dk-latin1',
|
|
|
'timezone': 'Europe/Copenhagen',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'dk',
|
|
|
'language': 'da',
|
|
|
}),
|
|
|
('de_DE', {
|
|
|
'name': 'Deutsch (Deutschland)',
|
|
|
'locale': 'de_DE.UTF-8',
|
|
|
'keymap': 'de-latin1',
|
|
|
'timezone': 'Europe/Berlin',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'de',
|
|
|
'language': 'de',
|
|
|
}),
|
|
|
('en_AU', {
|
|
|
'name': 'English (Australia)',
|
|
|
'locale': 'en_AU.UTF-8',
|
|
|
'keymap': 'us',
|
|
|
'timezone': 'Australia/Canberra',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us',
|
|
|
'language': 'en_AU',
|
|
|
}),
|
|
|
('en_GB', {
|
|
|
'name': 'English (United Kingdom)',
|
|
|
'locale': 'en_GB.UTF-8',
|
|
|
'keymap': 'uk',
|
|
|
'timezone': 'Europe/London',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'gb',
|
|
|
'language': 'en_GB',
|
|
|
}),
|
|
|
('en_US', {
|
|
|
'name': 'English (United States)',
|
|
|
'locale': 'en_US.UTF-8',
|
|
|
'keymap': 'us',
|
|
|
'timezone': 'America/New_York',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us',
|
|
|
'language': 'en',
|
|
|
}),
|
|
|
('es_ES', {
|
|
|
'name': 'Español (España)',
|
|
|
'locale': 'es_ES.UTF-8',
|
|
|
'keymap': 'es euro2',
|
|
|
'timezone': 'Europe/Madrid',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'es',
|
|
|
'language': 'es',
|
|
|
}),
|
|
|
('es_UY', {
|
|
|
'name': 'Español (Uruguay)',
|
|
|
'locale': 'es_UY.UTF-8',
|
|
|
'keymap': 'la-latin1',
|
|
|
'timezone': 'America/Montevideo',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'latam',
|
|
|
'language': 'es_UY',
|
|
|
}),
|
|
|
('es_VE', {
|
|
|
'name': 'Español (Venezuela)',
|
|
|
'locale': 'es_VE.UTF-8',
|
|
|
'keymap': 'la-latin1',
|
|
|
'timezone': 'America/Caracas',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'latam',
|
|
|
'language': 'es_UY',
|
|
|
}),
|
|
|
('et_EE', {
|
|
|
'name': 'Eesti (Eesti)',
|
|
|
'locale': 'et_EE.UTF-8',
|
|
|
'keymap': 'et',
|
|
|
'timezone': 'Europe/Tallinn',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'ee',
|
|
|
'language': 'et',
|
|
|
}),
|
|
|
('fr_BE', {
|
|
|
'name': 'Français (Belgique)',
|
|
|
'locale': 'fr_BE.UTF-8',
|
|
|
'keymap': 'be-latin1',
|
|
|
'timezone': 'Europe/Brussels',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'be',
|
|
|
'language': 'fr',
|
|
|
}),
|
|
|
('fr_CA', {
|
|
|
'name': 'Français (Canada)',
|
|
|
'locale': 'fr_CA.UTF-8',
|
|
|
'keymap': 'cf',
|
|
|
'timezone': 'Canada/Pacific',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'ca',
|
|
|
'language': 'fr',
|
|
|
}),
|
|
|
('fr_FR', {
|
|
|
'name': 'Français (France)',
|
|
|
'locale': 'fr_FR.UTF-8',
|
|
|
'keymap': 'fr-latin9',
|
|
|
'timezone': 'Europe/Paris',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'fr',
|
|
|
'language': 'fr',
|
|
|
}),
|
|
|
('hr_HR', {
|
|
|
'name': 'Hrvatski (Hrvatska)',
|
|
|
'locale': 'hr_HR.UTF-8',
|
|
|
'keymap': 'croat',
|
|
|
'timezone': 'Europe/Zagreb',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'hr',
|
|
|
'language': 'hr',
|
|
|
}),
|
|
|
('is_IS', {
|
|
|
'name': 'Íslenska (Ísland)',
|
|
|
'locale': 'is_IS.UTF-8',
|
|
|
'keymap': 'is-latin1',
|
|
|
'timezone': 'Atlantic/Reykjavik',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'is',
|
|
|
'language': 'is',
|
|
|
}),
|
|
|
('it_IT', {
|
|
|
'name': 'Italiano (Italia)',
|
|
|
'locale': 'it_IT.UTF-8',
|
|
|
'keymap': 'it',
|
|
|
'dumpkeys_charset': '',
|
|
|
'timezone': 'Europe/Rome',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'it',
|
|
|
'language': 'it',
|
|
|
}),
|
|
|
('kk_KZ', {
|
|
|
'name': 'Қазақ тілі (Қазақстан)',
|
|
|
'locale': 'kk_KZ.UTF-8',
|
|
|
'keymap': 'kaz_gost-unicode',
|
|
|
'timezone': 'Asia/Almaty',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,kz',
|
|
|
'language': 'kk',
|
|
|
}),
|
|
|
('lt_LT', {
|
|
|
'name': 'Lietuvių (Lietuva)',
|
|
|
'locale': 'lt_LT.UTF-8',
|
|
|
'keymap': 'lt.baltic',
|
|
|
'timezone': 'Europe/Vilnius',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'lt',
|
|
|
'language': 'lt',
|
|
|
}),
|
|
|
('lv_LV', {
|
|
|
'name': 'Latviešu (Latvija)',
|
|
|
'locale': 'lv_LV.UTF-8',
|
|
|
'keymap': 'lv',
|
|
|
'timezone': 'Europe/Riga',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'lv',
|
|
|
'language': 'lv',
|
|
|
}),
|
|
|
('hu_HU', {
|
|
|
'name': 'Magyar (Magyarország)',
|
|
|
'locale': 'hu_HU.UTF-8',
|
|
|
'keymap': 'hu',
|
|
|
'timezone': 'Europe/Budapest',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'hu',
|
|
|
'language': 'hu',
|
|
|
}),
|
|
|
('nl_BE', {
|
|
|
'name': 'Nederlands (België)',
|
|
|
'locale': 'nl_BE.UTF-8',
|
|
|
'keymap': 'nl',
|
|
|
'timezone': 'Europe/Brussels',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'lat9w-16',
|
|
|
'xkblayout': 'nl',
|
|
|
'language': 'nl_BE',
|
|
|
}),
|
|
|
('nl_NL', {
|
|
|
'name': 'Nederlands (Nederland)',
|
|
|
'locale': 'nl_NL.UTF-8',
|
|
|
'keymap': 'nl',
|
|
|
'timezone': 'Europe/Amsterdam',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'nl',
|
|
|
'language': 'nl_NL',
|
|
|
}),
|
|
|
('nn_NO', {
|
|
|
'name': 'Nynorsk (Noreg)',
|
|
|
'locale': 'nn_NO.UTF-8',
|
|
|
'keymap': 'no-latin1',
|
|
|
'timezone': 'Europe/Oslo',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'no',
|
|
|
'language': 'nn',
|
|
|
}),
|
|
|
('pl_PL', {
|
|
|
'name': 'Polski (Polska)',
|
|
|
'locale': 'pl_PL.UTF-8',
|
|
|
'keymap': 'pl',
|
|
|
'timezone': 'Europe/Warsaw',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'pl',
|
|
|
'language': 'pl',
|
|
|
}),
|
|
|
('pt_BR', {
|
|
|
'name': 'Português (Brasil)',
|
|
|
'locale': 'pt_BR.UTF-8',
|
|
|
'keymap': 'br-abnt2',
|
|
|
'timezone': 'Brazil/East',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'br',
|
|
|
'language': 'pt_BR',
|
|
|
}),
|
|
|
('pt_PT', {
|
|
|
'name': 'Português (Portugal)',
|
|
|
'locale': 'pt_PT.UTF-8@euro',
|
|
|
'keymap': 'pt-latin9',
|
|
|
'dumpkeys_charset': '',
|
|
|
'timezone': 'Europe/Lisbon',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'pt',
|
|
|
'language': 'pt',
|
|
|
}),
|
|
|
('ro_RO', {
|
|
|
'name': 'Română (România)',
|
|
|
'locale': 'ro_RO.UTF-8',
|
|
|
'keymap': 'ro_win',
|
|
|
'timezone': 'Europe/Bucharest',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'ro',
|
|
|
'language': 'ro',
|
|
|
}),
|
|
|
('ru_RU', {
|
|
|
'name': 'Русский (Россия)',
|
|
|
'locale': 'ru_RU.UTF-8',
|
|
|
'keymap': '-u ruwin_cplk-UTF-8',
|
|
|
'timezone': 'Europe/Moscow',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,ru',
|
|
|
'language': 'ru',
|
|
|
}),
|
|
|
('sk_SK', {
|
|
|
'name': 'Slovenčina (Slovenská republika)',
|
|
|
'locale': 'sk_SK.UTF-8',
|
|
|
'keymap': 'sk-qwertz',
|
|
|
'dumpkeys_charset': '',
|
|
|
'timezone': 'Europe/Bratislava',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'sk',
|
|
|
'language': 'sk',
|
|
|
}),
|
|
|
('sl_SI', {
|
|
|
'name': 'Slovenščina (Slovenija)',
|
|
|
'locale': 'sl_SI.UTF-8',
|
|
|
'keymap': 'slovene',
|
|
|
'timezone': 'Europe/Ljubljana',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'si',
|
|
|
'language': 'sl',
|
|
|
}),
|
|
|
('sq_AL', {
|
|
|
'name': 'Shqip (Shqipëria)',
|
|
|
'locale': 'sq_AL.UTF-8',
|
|
|
'keymap': 'al',
|
|
|
'timezone': 'Europe/Tirane',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'al',
|
|
|
'language': 'sq',
|
|
|
}),
|
|
|
('sr_RS', {
|
|
|
'name': 'Српски (Србија)',
|
|
|
'locale': 'sr_RS.UTF-8',
|
|
|
'keymap': 'sr-unicode',
|
|
|
'timezone': 'Europe/Belgrade',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,rs',
|
|
|
'language': 'sr',
|
|
|
}),
|
|
|
('fi_FI', {
|
|
|
'name': 'Suomi (Suomi)',
|
|
|
'locale': 'fi_FI.UTF-8',
|
|
|
'keymap': 'fi-latin9',
|
|
|
'timezone': 'Europe/Helsinki',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'fi',
|
|
|
'language': 'fi',
|
|
|
}),
|
|
|
('sv_SE', {
|
|
|
'name': 'Svenska (Sverige)',
|
|
|
'locale': 'sv_SE.UTF-8',
|
|
|
'keymap': 'sv-latin1',
|
|
|
'timezone': 'Europe/Stockholm',
|
|
|
'dumpkeys_charset': '',
|
|
|
'consolefont': 'lat0-16',
|
|
|
'xkblayout': 'us,se',
|
|
|
'language': 'sv',
|
|
|
}),
|
|
|
('uk_UA', {
|
|
|
'name': 'Українська (Україна)',
|
|
|
'locale': 'uk_UA.UTF-8',
|
|
|
'keymap': 'ua-utf',
|
|
|
'timezone': 'Europe/Kiev',
|
|
|
'dumpkeys_charset': 'koi8-u',
|
|
|
'consolefont': 'ter-v14n',
|
|
|
'xkblayout': 'us,ua',
|
|
|
'language': 'ua',
|
|
|
})
|
|
|
])
|
|
|
|
|
|
def getLangs(self):
|
|
|
return self.langData.keys()
|
|
|
|
|
|
def getLanguages(self):
|
|
|
return map(lambda x: self.langData[x]['language'],
|
|
|
self.langData.keys())
|
|
|
|
|
|
def isLangExists(self, lang):
|
|
|
return lang in self.langData.keys()
|
|
|
|
|
|
def isValueInFieldExists(self, field, value):
|
|
|
return value in map(lambda x: self.langData[x][field],
|
|
|
self.langData.keys())
|
|
|
|
|
|
def getFields(self, field):
|
|
|
return [l[1][field] for l in self.langData.items()]
|
|
|
|
|
|
def getFieldByLang(self, field, lang):
|
|
|
return self.langData.get(lang, self.langData['en_US'])[field]
|
|
|
|
|
|
def getFieldByKeymap(self, field, keymap):
|
|
|
return self.langData.get(self.getLangByField('keymap', keymap),
|
|
|
self.langData['en_US'])[field]
|
|
|
|
|
|
def getLangByField(self, field, value):
|
|
|
langs = [lang[0] for lang in self.langData.items()
|
|
|
if lang[1][field] == value]
|
|
|
if not langs:
|
|
|
return 'en_US'
|
|
|
else:
|
|
|
return langs[0]
|
|
|
|
|
|
|
|
|
class VariableOsClockTimezone(ReadonlyVariable):
|
|
|
"""
|
|
|
Current timezone
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
zoneinfodir = "/usr/share/zoneinfo/"
|
|
|
timezonefile = "/etc/timezone"
|
|
|
# try get timezone from kernel calculate param
|
|
|
timezone = getValueFromCmdLine(
|
|
|
CmdlineParams.Calculate, CmdlineParams.Timezone)
|
|
|
if timezone and \
|
|
|
path.exists(path.join(zoneinfodir, timezone)):
|
|
|
return timezone
|
|
|
# get timezone from /etc/timezone
|
|
|
if path.exists(timezonefile):
|
|
|
return open(timezonefile, "r").read().strip()
|
|
|
return "UTC"
|
|
|
|
|
|
|
|
|
class VariableOsLocaleLocale(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Locale (example: ru_RU.UTF-8)
|
|
|
"""
|
|
|
env_var = "LANG"
|
|
|
|
|
|
def get(self):
|
|
|
# get locale from boot calculate param
|
|
|
locale_file = '/etc/env.d/02locale'
|
|
|
locale_val = getValueFromCmdLine(
|
|
|
CmdlineParams.Calculate, CmdlineParams.Locale)
|
|
|
if self.isLangExists(locale_val):
|
|
|
cmd_val = self.getFieldByLang('locale', locale_val)
|
|
|
else:
|
|
|
cmd_val = None
|
|
|
locale_val = getValueFromConfig(locale_file, self.env_var)
|
|
|
if self.isValueInFieldExists('locale', locale_val):
|
|
|
file_val = locale_val
|
|
|
else:
|
|
|
file_val = None
|
|
|
if file_val or cmd_val:
|
|
|
if self.GetBool('cl_system_boot_set'):
|
|
|
return cmd_val or file_val
|
|
|
else:
|
|
|
return file_val or cmd_val
|
|
|
if self.env_var in os.environ and os.environ[self.env_var] != "C":
|
|
|
return os.environ[self.env_var]
|
|
|
return self.getFieldByLang("locale", "default")
|
|
|
|
|
|
|
|
|
class VariableOsLocaleLang(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Language (example: ru_RU)
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
"""lang (example: ru_RU)"""
|
|
|
return self.getLangByField("locale", self.Get('os_locale_locale'))
|
|
|
|
|
|
|
|
|
class VariableOsLocaleLanguage(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Short lang name (example: ru)
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
return self.getFieldByLang("language", self.Get('os_locale_lang'))
|
|
|
|
|
|
|
|
|
class VariableOsLocaleXkb(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Keyboard layout for X server (example: us,ru)
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
"""xkb layouts (example: en,ru)"""
|
|
|
return self.getFieldByLang("xkblayout", self.Get('os_locale_lang'))
|
|
|
|
|
|
|
|
|
class VariableOsLocaleXkbname(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Keyboard layout name for X server (remove value in hooks)
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
locale_xkb = self.Get("os_locale_xkb")
|
|
|
if locale_xkb:
|
|
|
return locale_xkb.split("(")[0]
|
|
|
return ""
|
|
|
|
|
|
|
|
|
class VariableOsLocaleLatSet(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Локаль содержит раскладку совместимую с латиницей
|
|
|
|
|
|
Используется для отображения индикатора переключения языка
|
|
|
"""
|
|
|
|
|
|
def get(self):
|
|
|
"""xkb layouts (example: en,ru)"""
|
|
|
layout = self.Get('os_locale_xkbname').split(',')
|
|
|
if len(layout) == 1:
|
|
|
return self.On
|
|
|
else:
|
|
|
return self.Off
|
|
|
|
|
|
|
|
|
class VariableOsLang(ReadonlyVariable, Locale):
|
|
|
"""
|
|
|
Supported langs
|
|
|
"""
|
|
|
type = "list"
|
|
|
|
|
|
def get(self):
|
|
|
return self.getLangs()
|
|
|
|
|
|
def humanReadable(self):
|
|
|
return map(lambda x: self.getFieldByLang("name", x),
|
|
|
self.Get())
|