forked from shaba/openuds
pep related fixes
This commit is contained in:
parent
0021fd5ff9
commit
9b2e9000e7
@ -221,7 +221,7 @@ class Connection(Handler):
|
||||
return self.connection(True)
|
||||
|
||||
if len(self._args) == 4:
|
||||
# /connection/idService/idTransport/scrambler/hostname
|
||||
# /connection/idService/idTransport/scrambler/hostname
|
||||
return self.script()
|
||||
|
||||
raise RequestError('Invalid Request')
|
||||
|
@ -408,7 +408,7 @@ class SimpleLDAPAuthenticator(Authenticator):
|
||||
break
|
||||
if ok is False:
|
||||
raise Exception(_('Can\'t locate any group with the membership attribute specified'))
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
return [False, six.text_type(e)]
|
||||
|
||||
logger.debug('LDAP group class and group id attr seems to be correct')
|
||||
|
@ -185,7 +185,6 @@ class Environmentable(object):
|
||||
"""
|
||||
self._env = environment
|
||||
|
||||
|
||||
@property
|
||||
def cache(self):
|
||||
"""
|
||||
|
@ -102,7 +102,6 @@ class DelayedTaskRunner(object):
|
||||
now = getSqlDatetime()
|
||||
filt = Q(execution_time__lt=now) | Q(insert_date__gt=now + timedelta(seconds=30))
|
||||
# If next execution is before now or last execution is in the future (clock changed on this server, we take that task as executable)
|
||||
taskInstance = None
|
||||
try:
|
||||
with transaction.atomic(): # Encloses
|
||||
task = dbDelayedTask.objects.select_for_update().filter(filt).order_by('execution_time')[0] # @UndefinedVariable
|
||||
|
@ -85,9 +85,9 @@ class DownloadsManager(object):
|
||||
if _id not in self._downloadables:
|
||||
logger.error('ID {0} not found in {1}!!!'.format(_id, self._downloadables))
|
||||
raise Http404
|
||||
return self.__send_file(request, self._downloadables[_id]['name'], self._downloadables[_id]['path'], self._downloadables[_id]['mime'])
|
||||
return self._send_file(request, self._downloadables[_id]['name'], self._downloadables[_id]['path'], self._downloadables[_id]['mime'])
|
||||
|
||||
def __send_file(self, request, name, filename, mime):
|
||||
def _send_file(self, _, name, filename, mime):
|
||||
"""
|
||||
Send a file through Django without loading the whole file into
|
||||
memory at once. The FileWrapper will turn the file object into an
|
||||
|
@ -203,9 +203,9 @@ class ClusteredServiceProvider(ServiceProvider):
|
||||
|
||||
node = None
|
||||
|
||||
def isInNode(n):
|
||||
if serviceInstance.ensureExistsOnNode(n) is True:
|
||||
node = n
|
||||
# def isInNode(n):
|
||||
# if serviceInstance.ensureExistsOnNode(n) is True:
|
||||
# node = n
|
||||
|
||||
pool = ThreadPool(10)
|
||||
|
||||
|
@ -38,6 +38,7 @@ from uds.core.util.State import State
|
||||
__updated__ = '2014-11-11'
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
class ClusteredUserDeployment(UserDeployment):
|
||||
|
||||
def startMigration(self, dstNode):
|
||||
|
@ -95,6 +95,7 @@ class ServiceInMaintenanceMode(ServiceException):
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ServiceAccessDeniedByCalendar(ServiceException):
|
||||
"""
|
||||
This service can't be accessed right now, probably due to date-time restrictions
|
||||
|
@ -338,7 +338,7 @@ class GlobalConfig(object):
|
||||
for d in os.listdir(os.path.join(os.path.dirname(uds.__file__), 'templates', 'uds')):
|
||||
if d not in ('admin', 'reports'): # Exclude folders with own internal templates
|
||||
themes.append(d)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
GlobalConfig.UDS_THEME.setParams(themes)
|
||||
@ -375,5 +375,6 @@ class GlobalConfig(object):
|
||||
|
||||
|
||||
# Context processor
|
||||
# noinspection PyUnusedLocal
|
||||
def context_processor(request):
|
||||
return {'css_path': GlobalConfig.CSS.get()}
|
||||
|
@ -62,7 +62,7 @@ class FileStorage(Storage):
|
||||
|
||||
try:
|
||||
cache = caches[cacheName]
|
||||
except:
|
||||
except Exception:
|
||||
logger.info('No cache for FileStorage configured.')
|
||||
cache = None
|
||||
|
||||
|
@ -91,6 +91,7 @@ def extractKey(dictionary, key, **kwargs):
|
||||
value = default
|
||||
return value
|
||||
|
||||
|
||||
_browsers = {
|
||||
'ie': [OsDetector.IExplorer],
|
||||
'opera': [OsDetector.Opera],
|
||||
|
@ -208,4 +208,5 @@ def _initializeData():
|
||||
CT_STORAGE: _('Storage')
|
||||
}
|
||||
|
||||
|
||||
_initializeData()
|
||||
|
@ -127,4 +127,5 @@ def _initializeData():
|
||||
Authenticator: OT_AUTHENTICATOR,
|
||||
}
|
||||
|
||||
|
||||
_initializeData()
|
||||
|
@ -65,7 +65,7 @@ class DBFile(UUIDModel):
|
||||
try:
|
||||
self.delete() # Autodelete, invalid...
|
||||
pass
|
||||
except:
|
||||
except Exception:
|
||||
logger.error('Could not even delete {}!!'.format(self.name))
|
||||
|
||||
return ''
|
||||
|
@ -112,4 +112,5 @@ class Group(UUIDModel):
|
||||
|
||||
logger.debug('Deleted group {0}'.format(toDelete))
|
||||
|
||||
|
||||
signals.pre_delete.connect(Group.beforeDelete, sender=Group)
|
||||
|
@ -15,6 +15,7 @@ from uds.core.ui import gui
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getResources(parameters):
|
||||
"""
|
||||
This helper is designed as a callback for Project Selector
|
||||
@ -32,8 +33,8 @@ def getResources(parameters):
|
||||
images = [gui.choiceItem(z['id'], z['name']) for z in api.getImages(ou=parameters['ou'])]
|
||||
|
||||
data = [
|
||||
{'name': 'lab', 'values': labs },
|
||||
{'name': 'image', 'values': images },
|
||||
{'name': 'lab', 'values': labs},
|
||||
{'name': 'image', 'values': images},
|
||||
]
|
||||
logger.debug('Return data: {}'.format(data))
|
||||
return data
|
||||
|
@ -47,141 +47,142 @@ AUTH = {
|
||||
}
|
||||
|
||||
INFO = {
|
||||
"project": "OpenGnsys",
|
||||
"version": "1.1.0pre",
|
||||
"release": "r5299",
|
||||
"services": [
|
||||
"server",
|
||||
"repository",
|
||||
"tracker"
|
||||
],
|
||||
"oglive": [
|
||||
{
|
||||
"distribution": "xenial",
|
||||
"kernel": "4.8.0-39-generic",
|
||||
"architecture": "amd64",
|
||||
"revision": "r5225",
|
||||
"directory": "ogLive-xenial-4.8.0-amd64-r5225",
|
||||
"iso": "ogLive-xenial-4.8.0-39-generic-amd64-r5225.iso"
|
||||
},
|
||||
{
|
||||
"iso": "ogLive-precise-3.2.0-23-generic-r4820.iso",
|
||||
"directory": "ogLive-precise-3.2.0-i386-r4820",
|
||||
"revision": "r4820",
|
||||
"architecture": "i386",
|
||||
"kernel": "3.2.0-23-generic",
|
||||
"distribution": "precise"
|
||||
} ]
|
||||
"project": "OpenGnsys",
|
||||
"version": "1.1.0pre",
|
||||
"release": "r5299",
|
||||
"services": [
|
||||
"server",
|
||||
"repository",
|
||||
"tracker"
|
||||
],
|
||||
"oglive": [
|
||||
{
|
||||
"distribution": "xenial",
|
||||
"kernel": "4.8.0-39-generic",
|
||||
"architecture": "amd64",
|
||||
"revision": "r5225",
|
||||
"directory": "ogLive-xenial-4.8.0-amd64-r5225",
|
||||
"iso": "ogLive-xenial-4.8.0-39-generic-amd64-r5225.iso"
|
||||
},
|
||||
{
|
||||
"iso": "ogLive-precise-3.2.0-23-generic-r4820.iso",
|
||||
"directory": "ogLive-precise-3.2.0-i386-r4820",
|
||||
"revision": "r4820",
|
||||
"architecture": "i386",
|
||||
"kernel": "3.2.0-23-generic",
|
||||
"distribution": "precise"
|
||||
}]
|
||||
}
|
||||
|
||||
OUS = [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Unidad Organizativa (Default)"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Unidad Organizatva VACIA"
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Unidad Organizativa (Default)"
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Unidad Organizatva VACIA"
|
||||
},
|
||||
]
|
||||
|
||||
LABS = [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Sala de control",
|
||||
"inremotepc": True,
|
||||
"group": {
|
||||
"id": "0"
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Sala de control",
|
||||
"inremotepc": True,
|
||||
"group": {
|
||||
"id": "0"
|
||||
},
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
"ou": {
|
||||
"id": "1"
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Sala de computación cuántica",
|
||||
"inremotepc": True,
|
||||
"group": {
|
||||
"id": "0"
|
||||
},
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Sala de computación cuántica",
|
||||
"inremotepc": True,
|
||||
"group": {
|
||||
"id": "0"
|
||||
},
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
IMAGES = [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Basica1604",
|
||||
"inremotepc": True,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Ubuntu16",
|
||||
"inremotepc": True,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"name": "Ubuntu64 Not in Remote",
|
||||
"inremotepc": False,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"name": "Ubuntu96 Not In Remote",
|
||||
"inremotepc": False,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Basica1604",
|
||||
"inremotepc": True,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"name": "Ubuntu16",
|
||||
"inremotepc": True,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"name": "Ubuntu64 Not in Remote",
|
||||
"inremotepc": False,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"name": "Ubuntu96 Not In Remote",
|
||||
"inremotepc": False,
|
||||
"ou": {
|
||||
"id": "1"
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
RESERVE = {
|
||||
"id": 4,
|
||||
"name": "pcpruebas",
|
||||
"mac": "4061860521FE",
|
||||
"ip": "10.1.14.31",
|
||||
"lab": {
|
||||
"id": 1
|
||||
},
|
||||
"ou": {
|
||||
"id": 1
|
||||
}
|
||||
"id": 4,
|
||||
"name": "pcpruebas",
|
||||
"mac": "4061860521FE",
|
||||
"ip": "10.1.14.31",
|
||||
"lab": {
|
||||
"id": 1
|
||||
},
|
||||
"ou": {
|
||||
"id": 1
|
||||
}
|
||||
}
|
||||
|
||||
UNRESERVE = ''
|
||||
|
||||
STATUS_OFF = {
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "off",
|
||||
"loggedin": False
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "off",
|
||||
"loggedin": False
|
||||
}
|
||||
|
||||
# A couple of status for testing
|
||||
STATUS_READY_LINUX = {
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "linux",
|
||||
"loggedin": False
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "linux",
|
||||
"loggedin": False
|
||||
}
|
||||
|
||||
STATUS_READY_WINDOWS = {
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "windows",
|
||||
"loggedin": False
|
||||
"id": 4,
|
||||
"ip": "10.1.14.31",
|
||||
"status": "windows",
|
||||
"loggedin": False
|
||||
}
|
||||
|
||||
|
||||
# FAKE post
|
||||
def post(path, data, errMsg):
|
||||
logger.info('FAKE POST request to {} with {} data. ({})'.format(path, data, errMsg))
|
||||
@ -190,11 +191,12 @@ def post(path, data, errMsg):
|
||||
elif path == urls.RESERVE.format(ou=1, image=1) or path == urls.RESERVE.format(ou=1, image=2):
|
||||
res = copy.deepcopy(RESERVE)
|
||||
res['name'] += six.text_type(random.randint(5000, 100000))
|
||||
res['mac'] = ''.join(random.choice('0123456789ABCDEF') for __ in range(12))
|
||||
res['mac'] = ''.join(random.choice('0123456789ABCDEF') for _ in range(12))
|
||||
return res
|
||||
|
||||
raise Exception('Unknown FAKE URL on POST: {}'.format(path))
|
||||
|
||||
|
||||
# FAKE get
|
||||
def get(path, errMsg):
|
||||
logger.info('FAKE GET request to {}. ({})'.format(path, errMsg))
|
||||
@ -220,6 +222,7 @@ def get(path, errMsg):
|
||||
|
||||
raise Exception('Unknown FAKE URL on GET: {}'.format(path))
|
||||
|
||||
|
||||
def delete(path, errMsg):
|
||||
logger.info('FAKE DELETE request to {}. ({})'.format(path, errMsg))
|
||||
# Right now, only "unreserve" uses delete, so simply return
|
||||
|
@ -15,6 +15,7 @@ from uds.core.ui import gui
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def getResources(parameters):
|
||||
"""
|
||||
This helper is designed as a callback for Project Selector
|
||||
@ -35,15 +36,16 @@ def getResources(parameters):
|
||||
volumeTypes = [gui.choiceItem('-', _('None'))] + [gui.choiceItem(t['id'], t['name']) for t in api.listVolumeTypes()]
|
||||
|
||||
data = [
|
||||
{'name': 'availabilityZone', 'values': zones },
|
||||
{'name': 'network', 'values': networks },
|
||||
{'name': 'flavor', 'values': flavors },
|
||||
{'name': 'securityGroups', 'values': securityGroups },
|
||||
{'name': 'volumeType', 'values': volumeTypes },
|
||||
{'name': 'availabilityZone', 'values': zones},
|
||||
{'name': 'network', 'values': networks},
|
||||
{'name': 'flavor', 'values': flavors},
|
||||
{'name': 'securityGroups', 'values': securityGroups},
|
||||
{'name': 'volumeType', 'values': volumeTypes},
|
||||
]
|
||||
logger.debug('Return data: {}'.format(data))
|
||||
return data
|
||||
|
||||
|
||||
def getVolumes(parameters):
|
||||
"""
|
||||
This helper is designed as a callback for Zone Selector
|
||||
@ -57,10 +59,11 @@ def getVolumes(parameters):
|
||||
|
||||
api = provider.api(parameters['project'], parameters['region'])
|
||||
|
||||
volumes = [gui.choiceItem(v['id'], v['name']) for v in api.listVolumes() if v['name'] != '' and v['availability_zone'] == parameters['availabilityZone']]
|
||||
volumes = [gui.choiceItem(v['id'], v['name']) for v in api.listVolumes() if
|
||||
v['name'] != '' and v['availability_zone'] == parameters['availabilityZone']]
|
||||
|
||||
data = [
|
||||
{'name': 'volume', 'values': volumes },
|
||||
{'name': 'volume', 'values': volumes},
|
||||
]
|
||||
logger.debug('Return data: {}'.format(data))
|
||||
return data
|
||||
|
@ -39,21 +39,26 @@ __updated__ = '2017-11-21'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
(ACTIVE, BUILDING, DELETED, ERROR,
|
||||
HARD_REBOOT, MIGRATING, PASSWORD,
|
||||
PAUSED, REBOOT, REBUILD, RESCUED,
|
||||
RESIZED, REVERT_RESIZE, SOFT_DELETED,
|
||||
STOPPED, SUSPENDED, UNKNOWN, VERIFY_RESIZE, SHUTOFF) = ('ACTIVE', 'BUILDING', 'DELETED', 'ERROR',
|
||||
'HARD_REBOOT', 'MIGRATING', 'PASSWORD',
|
||||
'PAUSED', 'REBOOT', 'REBUILD', 'RESCUED',
|
||||
'RESIZED', 'REVERT_RESIZE', 'SOFT_DELETED',
|
||||
'STOPPED', 'SUSPENDED', 'UNKNOWN', 'VERIFY_RESIZE', 'SHUTOFF')
|
||||
(
|
||||
ACTIVE, BUILDING, DELETED, ERROR,
|
||||
HARD_REBOOT, MIGRATING, PASSWORD,
|
||||
PAUSED, REBOOT, REBUILD, RESCUED,
|
||||
RESIZED, REVERT_RESIZE, SOFT_DELETED,
|
||||
STOPPED, SUSPENDED, UNKNOWN, VERIFY_RESIZE, SHUTOFF
|
||||
) = (
|
||||
'ACTIVE', 'BUILDING', 'DELETED', 'ERROR',
|
||||
'HARD_REBOOT', 'MIGRATING', 'PASSWORD',
|
||||
'PAUSED', 'REBOOT', 'REBUILD', 'RESCUED',
|
||||
'RESIZED', 'REVERT_RESIZE', 'SOFT_DELETED',
|
||||
'STOPPED', 'SUSPENDED', 'UNKNOWN', 'VERIFY_RESIZE', 'SHUTOFF'
|
||||
)
|
||||
|
||||
|
||||
# Helpers to check statuses
|
||||
def statusIsLost(status):
|
||||
return status in [DELETED, ERROR, UNKNOWN, SOFT_DELETED]
|
||||
|
||||
|
||||
def sanitizeName(name):
|
||||
"""
|
||||
machine names with [a-zA-Z0-9_-]
|
||||
|
@ -205,7 +205,7 @@ def ifbrowser(parser, token):
|
||||
cmd = token.split_contents()
|
||||
try:
|
||||
browsers = cmd[1:]
|
||||
except:
|
||||
except Exception:
|
||||
raise template.TemplateSyntaxError('{0} tag requires browsers to be checked')
|
||||
|
||||
states = {}
|
||||
|
@ -80,11 +80,13 @@ class HTML5RDPTransport(Transport):
|
||||
enableAudio = gui.CheckBoxField(label=_('Enable Audio'), order=24, tooltip=_('If checked, the audio will be redirected to client (if client browser supports it)'), tab=gui.PARAMETERS_TAB)
|
||||
enablePrinting = gui.CheckBoxField(label=_('Enable Printing'), order=25, tooltip=_('If checked, the printing will be redirected to client (if client browser supports it)'), tab=gui.PARAMETERS_TAB)
|
||||
enableFileSharing = gui.CheckBoxField(label=_('Enable File Sharing'), order=8, tooltip=_('If checked, the user will be able to upload/download files (if client browser supports it)'), tab=gui.PARAMETERS_TAB)
|
||||
serverLayout = gui.ChoiceField(order=26,
|
||||
serverLayout = gui.ChoiceField(
|
||||
order=26,
|
||||
label=_('Layout'),
|
||||
tooltip=_('Keyboards Layout of server'),
|
||||
required=True,
|
||||
values=[ gui.choiceItem('-', 'default'),
|
||||
values=[
|
||||
gui.choiceItem('-', 'default'),
|
||||
gui.choiceItem('en-us-qwerty', _('English (US) keyboard')),
|
||||
gui.choiceItem('de-de-qwertz', _('German keyboard (qwertz)')),
|
||||
gui.choiceItem('fr-fr-azerty', _('French keyboard (azerty)')),
|
||||
@ -95,7 +97,8 @@ class HTML5RDPTransport(Transport):
|
||||
defvalue='-',
|
||||
tab=gui.PARAMETERS_TAB
|
||||
)
|
||||
security = gui.ChoiceField(order=27,
|
||||
security = gui.ChoiceField(
|
||||
order=27,
|
||||
label=_('Security'),
|
||||
tooltip=_('Connection security mode for Guacamole RDP connection'),
|
||||
required=True,
|
||||
|
@ -33,12 +33,13 @@ def onExit():
|
||||
subprocess.call(
|
||||
[
|
||||
'security',
|
||||
'delete-generic-password',
|
||||
'-a', sp['usernameWithDomain'], # @UndefinedVariable
|
||||
'-s', 'Remote Desktop Connection 2 Password for {}'.format(sp['ip']), # @UndefinedVariable
|
||||
'delete-generic-password',
|
||||
'-a', sp['usernameWithDomain'], # @UndefinedVariable
|
||||
'-s', 'Remote Desktop Connection 2 Password for {}'.format(sp['ip']), # @UndefinedVariable
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
if executable is None:
|
||||
raise Exception('''<p><b>Microsoft Remote Desktop Connection not found</b></p>
|
||||
<p>In order to connect to UDS RDP Sessions, you need to have at least one of the following:<p>
|
||||
@ -48,7 +49,8 @@ if executable is None:
|
||||
<p>You can get it from <a href="{}static/other/CoRD.pkg">this link</a></p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>If both apps are installed, Remote Desktop Connection will be used as first option</p>'''.format(sp['this_server'])) # @UndefinedVariable
|
||||
<p>If both apps are installed, Remote Desktop Connection will be used as first option</p>'''.format(
|
||||
sp['this_server'])) # @UndefinedVariable
|
||||
elif executable == msrdc:
|
||||
try:
|
||||
filename = tools.saveTempFile(sp['as_file']) # @UndefinedVariable
|
||||
|
@ -130,17 +130,26 @@ class BaseX2GOTransport(Transport):
|
||||
{'id': '2', 'text': 'ADSL'},
|
||||
{'id': '3', 'text': 'WAN'},
|
||||
{'id': '4', 'text': 'LAN'},
|
||||
], tab=gui.PARAMETERS_TAB)
|
||||
],
|
||||
tab=gui.PARAMETERS_TAB
|
||||
)
|
||||
|
||||
soundType = gui.ChoiceField(label=_('Sound'), order=30, tooltip=_('Sound server'),
|
||||
soundType = gui.ChoiceField(
|
||||
label=_('Sound'),
|
||||
order=30,
|
||||
tooltip=_('Sound server'),
|
||||
defvalue='pulse',
|
||||
values=[
|
||||
{'id': 'pulse', 'text': 'Pulse'},
|
||||
{'id': 'esd', 'text': 'ESD'},
|
||||
], tab=gui.ADVANCED_TAB
|
||||
],
|
||||
tab=gui.ADVANCED_TAB
|
||||
)
|
||||
|
||||
keyboardLayout = gui.TextField(label=_('Keyboard'), order=31, tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
||||
keyboardLayout = gui.TextField(
|
||||
label=_('Keyboard'),
|
||||
order=31,
|
||||
tooltip=_('Keyboard layout (es, us, fr, ...). Empty value means autodetect.'),
|
||||
defvalue='',
|
||||
tab=gui.ADVANCED_TAB
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user