|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
# Copyright 2012-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.
|
|
|
|
|
|
|
|
|
|
|
|
import sys
|
|
|
import os
|
|
|
import argparse
|
|
|
import re
|
|
|
from calculate.lib.utils.common import getpass
|
|
|
from calculate.lib.cl_print import color_print
|
|
|
from calculate.lib.cl_lang import setLocalTranslate
|
|
|
from calculate.core.server.api_types import TableAdapter
|
|
|
from functools import reduce
|
|
|
|
|
|
_ = lambda x: x
|
|
|
setLocalTranslate('cl_core3', sys.modules[__name__])
|
|
|
from itertools import *
|
|
|
from .api_types import ViewInfoAdapter, ArrayReturnedMessage, FieldAdapter
|
|
|
from calculate.lib.utils.colortext import get_terminal_print, TextState
|
|
|
|
|
|
colorPrint = color_print()
|
|
|
|
|
|
|
|
|
class GotErrorField(Exception):
|
|
|
"""
|
|
|
Исключение о получение поля error среди
|
|
|
элементов view
|
|
|
"""
|
|
|
pass
|
|
|
|
|
|
|
|
|
class BoolAction(argparse.Action):
|
|
|
reTrue = re.compile("^(?:on|yes)$", re.I)
|
|
|
reFalse = re.compile("^(?:off|no)$", re.I)
|
|
|
available_values = ("on", "off","yes", "no")
|
|
|
|
|
|
def __init__(self, option_strings, dest, nargs="?",
|
|
|
const=None, default=None, type=None, choices=None,
|
|
|
required=False, help=None, metavar=None):
|
|
|
super().__init__(
|
|
|
option_strings=option_strings, dest=dest,
|
|
|
nargs=nargs, const=const, default=default,
|
|
|
type=type, choices=choices, required=required,
|
|
|
help=help, metavar=metavar)
|
|
|
|
|
|
def get_values(self, value):
|
|
|
value = value.lower()
|
|
|
for v in self.available_values:
|
|
|
if value == v:
|
|
|
return v
|
|
|
else:
|
|
|
return ""
|
|
|
|
|
|
def __call__(self, parser, ns, values, option_string=None):
|
|
|
if values is None:
|
|
|
values = "on"
|
|
|
else:
|
|
|
if self.reTrue.match(values):
|
|
|
values = "on"
|
|
|
if self.reFalse.match(values):
|
|
|
values = "off"
|
|
|
values = self.get_values(values)
|
|
|
if not values:
|
|
|
msg = _('the value may be {0}').format(
|
|
|
formatListOr(self.available_values))
|
|
|
parser.error(msg)
|
|
|
setattr(ns, self.dest, values)
|
|
|
|
|
|
class BoolAutoAction(BoolAction):
|
|
|
available_values = ("on", "off", "yes", "no", "auto")
|
|
|
|
|
|
def _print(*args):
|
|
|
print(" ".join((_u8(x) for x in args)))
|
|
|
|
|
|
|
|
|
def get_password(text1=None, text2=None, getfromstdin=False,
|
|
|
needrepeat=True):
|
|
|
if getfromstdin:
|
|
|
try:
|
|
|
passwd = ''
|
|
|
while not passwd:
|
|
|
passwd = sys.stdin.readline()
|
|
|
if not passwd:
|
|
|
return None
|
|
|
passwd = passwd.rstrip('\n')
|
|
|
return passwd
|
|
|
except BaseException:
|
|
|
return None
|
|
|
if not text1:
|
|
|
text1 = _('Password: ')
|
|
|
if not text2:
|
|
|
text2 = _('Repeat: ')
|
|
|
try:
|
|
|
pass1 = 'password'
|
|
|
pass2 = 'repeat'
|
|
|
while pass1 != pass2:
|
|
|
pass1 = getpass.getpass(text1)
|
|
|
if not needrepeat:
|
|
|
return pass1
|
|
|
pass2 = getpass.getpass(text2)
|
|
|
if pass1 != pass2:
|
|
|
print(_('Passwords do not match'))
|
|
|
except KeyboardInterrupt:
|
|
|
return None
|
|
|
passwd = pass1 if (pass1 and pass1 == pass2) else ''
|
|
|
return passwd
|
|
|
|
|
|
|
|
|
def listToArray(client, _list, _type='string'):
|
|
|
if not client:
|
|
|
return _list
|
|
|
array = client.factory.create('%sArray' % _type)
|
|
|
for i in _list:
|
|
|
array['%s' % _type].append(i)
|
|
|
return array
|
|
|
|
|
|
|
|
|
def listToArrayArray(client, _list, _type='string'):
|
|
|
if not client:
|
|
|
return _list
|
|
|
array_array = client.factory.create('%sArrayArray' % _type)
|
|
|
for i in _list:
|
|
|
array = client.factory.create('%sArray' % _type)
|
|
|
for j in i:
|
|
|
array[_type].append(j)
|
|
|
array_array['%sArray' % _type].append(array)
|
|
|
return array_array
|
|
|
|
|
|
|
|
|
def _getattr(obj, attr):
|
|
|
return getattr(obj, attr) if hasattr(obj, attr) else None
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
import textwrap as _textwrap
|
|
|
from calculate.lib.utils.text import get_term_size, _u, _u8, _uu8, formatListOr
|
|
|
|
|
|
|
|
|
class RawAndDefaultsHelpFormatter(argparse.HelpFormatter):
|
|
|
def __init__(self, prog, max_help_position=24, **kwargs):
|
|
|
# Use the whole terminal width
|
|
|
height, width = get_term_size()
|
|
|
argparse.HelpFormatter.__init__(self, prog, width=width,
|
|
|
max_help_position=max_help_position,
|
|
|
**kwargs)
|
|
|
|
|
|
def _split_lines(self, text, width):
|
|
|
text = self._whitespace_matcher.sub(' ', _u(text)).strip()
|
|
|
return _uu8(*_textwrap.wrap(text, width))
|
|
|
|
|
|
|
|
|
def get_method_argparser(view, args, cl_core=False):
|
|
|
"""
|
|
|
Get argparser by ViewInfo get from WSDL server (or stub)
|
|
|
|
|
|
cl_core - argparser for cl_core (local call)
|
|
|
"""
|
|
|
error_flag = False
|
|
|
method = args.method
|
|
|
if cl_core:
|
|
|
progr = os.path.basename(sys.argv[0])
|
|
|
else:
|
|
|
progr = 'cl-console --method ' + method
|
|
|
|
|
|
bool_vars = ["f"]
|
|
|
|
|
|
def fix_bool_variables(args):
|
|
|
prevlen = 0
|
|
|
local_args = args
|
|
|
while prevlen != len(local_args):
|
|
|
prevlen = len(local_args)
|
|
|
local_args = reduce(lambda x, y: (
|
|
|
x + [y[:2], "-%s" % y[2:]]
|
|
|
if (len(y) > 2 and y[:1] == "-" and y[1:2] in bool_vars and
|
|
|
not y[2:].lower().startswith("on") and
|
|
|
not y[2:].lower().startswith("off"))
|
|
|
else x + [y]), local_args, [])
|
|
|
return local_args
|
|
|
|
|
|
def get_list(data):
|
|
|
if data is not None:
|
|
|
for entry in data if cl_core else data[0]:
|
|
|
yield entry
|
|
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
prog=progr, add_help=False, formatter_class=RawAndDefaultsHelpFormatter)
|
|
|
parser.fixBoolVariables = fix_bool_variables
|
|
|
|
|
|
for Group in (x for x in get_list(view.groups) if x.fields):
|
|
|
group = parser.add_argument_group(Group.name)
|
|
|
for field in get_list(Group.fields):
|
|
|
if field.element == 'error':
|
|
|
error_flag = True
|
|
|
colorPrint.printERROR(field.label)
|
|
|
elif field.opt:
|
|
|
opt = field.opt
|
|
|
data = {'dest': field.name, 'help': opt.help}
|
|
|
if "choice" in field.type and hasattr(field.opt, "syntax") and \
|
|
|
field.opt.syntax and "{" in field.opt.syntax:
|
|
|
lgroup = group.add_mutually_exclusive_group()
|
|
|
help = dict(((x[0].strip("'"), x[2]) for x
|
|
|
in (y.partition(' - ') for y
|
|
|
in field.help.split(',\n'))))
|
|
|
choice = field.choice
|
|
|
if not type(choice) in (list, tuple):
|
|
|
choice = choice.string
|
|
|
for val in (x for x in choice if x):
|
|
|
data['action'] = 'store_const'
|
|
|
# data['nargs'] = '?'
|
|
|
data['const'] = val
|
|
|
data['metavar'] = ""
|
|
|
if hasattr(field, "value") and field.value == val:
|
|
|
data['help'] = (help.get(val, field.help) +
|
|
|
" " + _("(by default)"))
|
|
|
else:
|
|
|
data['help'] = help.get(val, field.help)
|
|
|
lgroup.add_argument(field.opt.syntax.format(choice=val),
|
|
|
**data)
|
|
|
continue
|
|
|
if "password" in field.type:
|
|
|
data['action'] = "store_true"
|
|
|
if "need" in field.type:
|
|
|
data['help'] = argparse.SUPPRESS
|
|
|
else:
|
|
|
data['type'] = str
|
|
|
if field.element in ['check', 'check_tristate']:
|
|
|
if field.element == "check_tristate":
|
|
|
data['action'] = BoolAutoAction
|
|
|
else:
|
|
|
data['action'] = BoolAction
|
|
|
if field.value == 'on':
|
|
|
data['help'] = data['help'] + " " + _(
|
|
|
"(enabled by default)")
|
|
|
if opt.shortopt:
|
|
|
bool_vars.append(opt.shortopt[1])
|
|
|
elif field.element == 'radio' and field.type == 'bool':
|
|
|
data['action'] = BoolAction
|
|
|
if field.value == 'on':
|
|
|
data['help'] = data['help'] + " " + _(
|
|
|
"(enabled by default)")
|
|
|
if opt.shortopt:
|
|
|
bool_vars.append(opt.shortopt[1])
|
|
|
if field.element == 'table' and field.type != 'steps':
|
|
|
data['action'] = 'append'
|
|
|
|
|
|
if data.get('action') != "store_true":
|
|
|
data['metavar'] = opt.metavalue if opt.metavalue \
|
|
|
else field.name.upper()
|
|
|
# if ':' in data['metavar']:
|
|
|
# data['metavar'] = field.name.upper()
|
|
|
if "choice" in field.type:
|
|
|
if "list" in field.type:
|
|
|
data['help'] = "%s (%s)" % (
|
|
|
data['help'],
|
|
|
_("'list' for displaying possible values, "
|
|
|
"'none' is never one"))
|
|
|
else:
|
|
|
data['help'] = "%s (%s)" % (
|
|
|
data['help'],
|
|
|
_("'list' for displaying possible values"))
|
|
|
if "boolauto" in field.type:
|
|
|
data['metavar'] = "ON/OFF/AUTO"
|
|
|
elif "bool3" in field.type:
|
|
|
data['metavar'] = "ON/OFF/AUTO"
|
|
|
elif "bool" in field.type:
|
|
|
data['metavar'] = "ON/OFF"
|
|
|
try:
|
|
|
opts = [x for x in [opt.shortopt, opt.longopt] if x]
|
|
|
if any("-" not in x for x in opts):
|
|
|
data.pop('dest')
|
|
|
data['nargs'] = '?'
|
|
|
group.add_argument(*opts, **data)
|
|
|
except argparse.ArgumentError:
|
|
|
continue
|
|
|
group = parser.add_argument_group(_("Common arguments"))
|
|
|
group.add_argument(
|
|
|
'-f', '--force', action='store_true', default=False,
|
|
|
dest='no_questions', help=_('silent during the process'))
|
|
|
if error_flag:
|
|
|
raise GotErrorField
|
|
|
return parser
|
|
|
|
|
|
|
|
|
def set_obj_item(client, param_object, field_name, value):
|
|
|
"""
|
|
|
Set value for Info object. By client detect (local or WSDL call)
|
|
|
"""
|
|
|
if client:
|
|
|
param_object.__setitem__(field_name, value)
|
|
|
else:
|
|
|
setattr(param_object, field_name, value)
|
|
|
return param_object
|
|
|
|
|
|
|
|
|
def set_table_pwd(client, param_object, field, value):
|
|
|
if type(field.tablevalue.values) in [list, tuple]:
|
|
|
choice_values = field.tablevalue.values
|
|
|
# column = len(field.tablevalue.head)
|
|
|
else:
|
|
|
choice_values = field.tablevalue.values.ChoiceValue
|
|
|
# column = len(field.tablevalue.head.string)
|
|
|
# print ChoiceValue, column
|
|
|
found_flag = False
|
|
|
changed_string = None
|
|
|
if not getattr(param_object, field.name):
|
|
|
for column in range(len(choice_values)):
|
|
|
if found_flag:
|
|
|
break
|
|
|
if "password" in choice_values[column].typefield:
|
|
|
if hasattr(field.tablevalue.body, 'stringArray'):
|
|
|
body = field.tablevalue.body.stringArray
|
|
|
else:
|
|
|
body = field.tablevalue.body
|
|
|
for _row in body:
|
|
|
if hasattr(_row, 'string'):
|
|
|
row = _row.string
|
|
|
else:
|
|
|
if not _row[0]:
|
|
|
row = _row[1:]
|
|
|
else:
|
|
|
row = _row
|
|
|
if not row[column]:
|
|
|
row[column] = value
|
|
|
temp = []
|
|
|
for item in row:
|
|
|
temp.append(item) if item else temp.append('')
|
|
|
changed_string = temp
|
|
|
found_flag = True
|
|
|
break
|
|
|
else:
|
|
|
user_table = getattr(param_object, field.name)
|
|
|
if hasattr(user_table, 'stringArray'):
|
|
|
user_table = user_table.stringArray
|
|
|
for column in range(len(choice_values)):
|
|
|
if found_flag:
|
|
|
break
|
|
|
if "password" in choice_values[column].typefield:
|
|
|
for _row in user_table:
|
|
|
if hasattr(_row, 'string'):
|
|
|
row = _row.string
|
|
|
else:
|
|
|
if not _row[0]:
|
|
|
row = _row[1:]
|
|
|
else:
|
|
|
row = _row
|
|
|
if not row[column]:
|
|
|
row[column] = value
|
|
|
temp = []
|
|
|
for item in row:
|
|
|
temp.append(item) if item else temp.append('')
|
|
|
changed_string = temp
|
|
|
found_flag = True
|
|
|
break
|
|
|
|
|
|
# код выполняется через сетевую консоль
|
|
|
if client:
|
|
|
if not getattr(param_object, field.name):
|
|
|
setattr(param_object, field.name, field.tablevalue.body)
|
|
|
object_array = TableAdapter.get_matrix(param_object[field.name])
|
|
|
# код выполняется локально
|
|
|
else:
|
|
|
if not getattr(param_object, field.name):
|
|
|
setattr(param_object, field.name,
|
|
|
[x[1:] if not x[0] else x for x
|
|
|
in field.tablevalue.body])
|
|
|
object_array = getattr(param_object, field.name)
|
|
|
|
|
|
result = []
|
|
|
for _array in object_array:
|
|
|
temp = []
|
|
|
for item in _array:
|
|
|
temp.append(item) if item else temp.append('')
|
|
|
result.append(temp)
|
|
|
if changed_string:
|
|
|
for item in result:
|
|
|
if str(item[0]) == str(changed_string[0]):
|
|
|
result.remove(item)
|
|
|
|
|
|
result.append(changed_string)
|
|
|
|
|
|
if client:
|
|
|
param_object[field.name] = listToArrayArray(client, result)
|
|
|
else:
|
|
|
setattr(param_object, field.name, result)
|
|
|
return param_object
|
|
|
|
|
|
|
|
|
def display_error(error, args, groups):
|
|
|
params_text = ''
|
|
|
sys.stdout.write('\r')
|
|
|
sys.stdout.flush()
|
|
|
list_answer = False
|
|
|
varname, comments, values, value, list_value = None, None, None, None, []
|
|
|
if error.type != "commonerror":
|
|
|
for group in groups:
|
|
|
for field in group.fields:
|
|
|
if field.name == error.field:
|
|
|
if args is not None:
|
|
|
if (getattr(args, field.name) == "list" and
|
|
|
"choice" in field.type):
|
|
|
if error.field_obj:
|
|
|
field_obj = FieldAdapter.from_detect(error.field_obj)
|
|
|
list_answer = True
|
|
|
varname = (field_obj.label or
|
|
|
field_obj.name)
|
|
|
comments = field_obj.comments
|
|
|
values = field_obj.choice
|
|
|
value = field_obj.value
|
|
|
list_value = error.field_obj.listvalue or []
|
|
|
params_text += getErrorOnParam(args, field)
|
|
|
else:
|
|
|
if field.opt.shortopt or field.opt.longopt:
|
|
|
params_text += _('Wrong option ')
|
|
|
params_text += ' ' + ', '.join((x for x
|
|
|
in [field.opt.shortopt,field.opt.longopt] if x)) + '. %s'
|
|
|
if list_answer:
|
|
|
__print = get_terminal_print(colorPrint.defaultPrint)
|
|
|
__print.foreground(TextState.Colors.WHITE)(
|
|
|
_("%s values:") % varname)
|
|
|
__print("\n")
|
|
|
if comments and values:
|
|
|
maxlen = len(max(values, key=len))
|
|
|
for v, c in zip(values, comments):
|
|
|
if not v and not c:
|
|
|
continue
|
|
|
__print(" ")
|
|
|
__print.bold("[" + v + "]")
|
|
|
__print(" " * (maxlen - len(v)))
|
|
|
__print(" ")
|
|
|
__print(c)
|
|
|
if value == v or v in list_value:
|
|
|
__print(" ")
|
|
|
__print.bold.foreground(TextState.Colors.WHITE)("*")
|
|
|
__print("\n")
|
|
|
if not comments:
|
|
|
for v in (x for x in values if x):
|
|
|
__print(" ")
|
|
|
__print.bold("[" + v + "]")
|
|
|
if value == v:
|
|
|
__print(" ")
|
|
|
__print.bold.foreground(TextState.Colors.WHITE)("*")
|
|
|
__print("\n")
|
|
|
elif error.type != "commonerror":
|
|
|
colorPrint.printERROR(params_text % error)
|
|
|
else:
|
|
|
colorPrint.printWARNING(error)
|
|
|
|
|
|
|
|
|
def check_result_msg(method_result, view, input_error_dict=None, args=None):
|
|
|
if not input_error_dict:
|
|
|
input_error_dict = {}
|
|
|
password_errors = {}
|
|
|
method_result = ArrayReturnedMessage.from_detect(method_result)
|
|
|
view = ViewInfoAdapter.from_detect(view)
|
|
|
|
|
|
for error in method_result:
|
|
|
if error.type == 'pwderror':
|
|
|
password_errors[error.field] = error
|
|
|
continue
|
|
|
|
|
|
display_error(error, args, view.groups)
|
|
|
|
|
|
# если все ошибки связаны с паролем
|
|
|
if len(password_errors) == len(method_result):
|
|
|
if (not dict([x for x in input_error_dict.items()
|
|
|
if x not in password_errors.items()]) and
|
|
|
not dict([x for x in password_errors.items()
|
|
|
if x not in input_error_dict.items()])):
|
|
|
return None
|
|
|
return password_errors
|
|
|
else:
|
|
|
return None
|
|
|
|
|
|
|
|
|
def get_param_pwd(check_res, view, param_object, client=None,
|
|
|
stdin_passwd=False):
|
|
|
view = ViewInfoAdapter.from_detect(view)
|
|
|
for pwd_field in check_res:
|
|
|
if not stdin_passwd:
|
|
|
_print(check_res[pwd_field])
|
|
|
for group in view.groups:
|
|
|
for field in group.fields:
|
|
|
if field.name == pwd_field:
|
|
|
if field.element == 'table':
|
|
|
value = get_password(getfromstdin=stdin_passwd)
|
|
|
if value is None:
|
|
|
_print(check_res[pwd_field])
|
|
|
raise KeyboardInterrupt
|
|
|
set_table_pwd(client, param_object, field, value)
|
|
|
else:
|
|
|
value = get_password(getfromstdin=stdin_passwd)
|
|
|
if value is None:
|
|
|
_print(check_res[pwd_field])
|
|
|
raise KeyboardInterrupt
|
|
|
setattr(param_object, pwd_field, value)
|
|
|
return param_object
|
|
|
|
|
|
|
|
|
def collect_object(client, param_object, view, args, wait_thread=None,
|
|
|
stdin_passwd=False):
|
|
|
"""
|
|
|
Collect Info object by args
|
|
|
"""
|
|
|
steps = None
|
|
|
view = ViewInfoAdapter.from_detect(view)
|
|
|
for group in view.groups:
|
|
|
for field in group.fields:
|
|
|
#if field.uncompatible:
|
|
|
# continue
|
|
|
if (field.element in ['check', 'check_tristate'] and
|
|
|
field.type in ('bool', 'boolauto', 'bool3')) or (
|
|
|
field.element == 'radio' and field.type == 'bool'):
|
|
|
value = _getattr(args, field.name)
|
|
|
if field.type == 'bool3':
|
|
|
pass
|
|
|
else:
|
|
|
if value:
|
|
|
if _getattr(args, field.name).lower() in ['on', 'yes']:
|
|
|
value = True
|
|
|
elif _getattr(args,
|
|
|
field.name).lower() in ['off', 'no']:
|
|
|
value = False
|
|
|
else:
|
|
|
value = None
|
|
|
else:
|
|
|
value = None
|
|
|
param_object = set_obj_item(client, param_object,
|
|
|
field.name, value)
|
|
|
elif (field.element == 'input' and
|
|
|
field.name in ['cl_page_offset', 'cl_page_count']):
|
|
|
val = _getattr(args, field.name)
|
|
|
if not val:
|
|
|
val = 0
|
|
|
if wait_thread:
|
|
|
wait_thread.stop()
|
|
|
# param_object[field.name] = val
|
|
|
param_object = set_obj_item(client, param_object, field.name,
|
|
|
val)
|
|
|
|
|
|
elif field.element in ['input', 'openfile',
|
|
|
'file', 'radio', 'combo', 'comboEdit']:
|
|
|
param_object = set_obj_item(client, param_object, field.name,
|
|
|
_getattr(args, field.name))
|
|
|
elif 'passw' in field.element and _getattr(args, field.name) \
|
|
|
or field.type and "need" in field.type:
|
|
|
if wait_thread:
|
|
|
wait_thread.pause()
|
|
|
label = field.label or _("Password")
|
|
|
password = get_password(label + _(": "),
|
|
|
_('Repeat password: '),
|
|
|
getfromstdin=stdin_passwd,
|
|
|
needrepeat="one" not in field.type)
|
|
|
if password is None:
|
|
|
raise KeyboardInterrupt
|
|
|
param_object = set_obj_item(client, param_object, field.name,
|
|
|
password)
|
|
|
if wait_thread:
|
|
|
wait_thread.resume()
|
|
|
elif field.element in ['multichoice', 'multichoice_add',
|
|
|
'selecttable', 'selecttable_add']:
|
|
|
val = _getattr(args, field.name)
|
|
|
if val in ['off', 'none']:
|
|
|
if client:
|
|
|
value = listToArray(client, [None])
|
|
|
else:
|
|
|
value = []
|
|
|
else:
|
|
|
value = listToArray(client,
|
|
|
val.split(',')) if val else None
|
|
|
param_object = set_obj_item(client, param_object, field.name,
|
|
|
value)
|
|
|
|
|
|
elif field.element == 'table' and field.type != 'steps':
|
|
|
val = _getattr(args, field.name)
|
|
|
value = collect_table(field, val, client, wait_thread,
|
|
|
stdin_passwd)
|
|
|
param_object = set_obj_item(client, param_object, field.name,
|
|
|
value)
|
|
|
|
|
|
elif field.element == 'table' and field.type == 'steps':
|
|
|
steps = field
|
|
|
if hasattr(param_object, 'CheckAll'):
|
|
|
param_object = set_obj_item(client, param_object, 'CheckAll', True)
|
|
|
|
|
|
return param_object, steps
|
|
|
|
|
|
|
|
|
def convertArgDictToList(argDict):
|
|
|
"""
|
|
|
Convert list of dict like {'arg_1':None,'arg_2':'value2','arg_5':'value5'}
|
|
|
to [..,['','value2','','','value5']..] (iterator)
|
|
|
"""
|
|
|
for row in argDict:
|
|
|
yield [row[i] or '' for i in sorted(row.keys())]
|
|
|
|
|
|
|
|
|
def collect_table(field, val_list, client, wait_thread=None,
|
|
|
stdin_passwd=False):
|
|
|
def split_param(l, delimeter=","):
|
|
|
for x in l:
|
|
|
for y in x.split(delimeter):
|
|
|
yield y
|
|
|
|
|
|
if not val_list:
|
|
|
return None
|
|
|
# if specified syntax for table row
|
|
|
if hasattr(field.opt, "syntax") and field.opt.syntax:
|
|
|
#TODO this could be buggy in py3, check
|
|
|
reArgs = re.compile(field.opt.syntax)
|
|
|
# check for correct sentense
|
|
|
for wrong in filterfalse(reArgs.search, val_list):
|
|
|
# raise Error on wrong
|
|
|
raise ValueError(_("Wrong %s value syntax") %
|
|
|
(field.opt.shortopt or field.opt.longopt)
|
|
|
+ " " + wrong)
|
|
|
# create groupdict from all vals
|
|
|
argDict = [x.groupdict() for x in map(reArgs.search, val_list)]
|
|
|
# convert groupdicts to val_table
|
|
|
val_table = list(convertArgDictToList(argDict))
|
|
|
# standard syntax
|
|
|
else:
|
|
|
reduced_list = list(val_list)
|
|
|
val_table = [x.split(':') for x in reduced_list]
|
|
|
|
|
|
if type(field.tablevalue.values) in [list, tuple]:
|
|
|
choiceValue = field.tablevalue.values
|
|
|
else:
|
|
|
choiceValue = field.tablevalue.values.ChoiceValue
|
|
|
choiceValue = [x for x in choiceValue if x.typefield != 'readonly']
|
|
|
lenChoiceValue = len(choiceValue)
|
|
|
for wrong in (x for x in val_table if len(x) > lenChoiceValue):
|
|
|
if type(wrong) in (list, tuple):
|
|
|
wrong = ":".join(wrong)
|
|
|
raise ValueError(_("Wrong %s value syntax") %
|
|
|
(field.opt.shortopt or field.opt.longopt)
|
|
|
+ " " + wrong)
|
|
|
|
|
|
# obj_body = []
|
|
|
|
|
|
# if type(field.tablevalue.body) == list:
|
|
|
# temp_body = field.tablevalue.body
|
|
|
# else:
|
|
|
# temp_body = field.tablevalue.body.stringArray
|
|
|
# for obj_row in temp_body:
|
|
|
# if type(obj_row) != list:
|
|
|
# obj_row = obj_row.string
|
|
|
# for item in range(len(obj_row)):
|
|
|
# if not obj_row[item]:
|
|
|
# obj_row[item] = ''
|
|
|
# else:
|
|
|
# if obj_row:
|
|
|
# if obj_row[0] == '':
|
|
|
# obj_row.pop(0)
|
|
|
# obj_body.append(obj_row)
|
|
|
#
|
|
|
# obj_body = collect_obj_body(obj_body, field)
|
|
|
|
|
|
is_password_get = any('password' in x.typefield for x in choiceValue)
|
|
|
obj_body = []
|
|
|
for line in val_table:
|
|
|
received_password = None
|
|
|
if is_password_get:
|
|
|
if len(line) > 0 and line[0].lower() != '':
|
|
|
if wait_thread:
|
|
|
wait_thread.stop()
|
|
|
sys.stdout.write('\r')
|
|
|
sys.stdout.flush()
|
|
|
received_password = get_password(
|
|
|
_('Password for %s: ') % line[0],
|
|
|
_('Repeat password for %s: ') % line[0],
|
|
|
getfromstdin=stdin_passwd)
|
|
|
if received_password is None:
|
|
|
raise KeyboardInterrupt
|
|
|
temp_row = []
|
|
|
for val, choice_value in zip_longest(
|
|
|
line, (x for x in choiceValue if x.typefield != 'readonly'),
|
|
|
fillvalue=''):
|
|
|
typefield = choice_value.typefield
|
|
|
# if readonly, except first column
|
|
|
if typefield in ['check', 'check_tristate']:
|
|
|
if BoolAction.reTrue.match(val):
|
|
|
temp_row.append('on')
|
|
|
elif BoolAction.reFalse.match(val):
|
|
|
temp_row.append('off')
|
|
|
else:
|
|
|
temp_row.append(val)
|
|
|
elif typefield in ['input', 'combo', 'comboEdit', 'openfile',
|
|
|
'file', 'radio', 'text', 'multichoice',
|
|
|
'multichoice_add']:
|
|
|
temp_row.append(val)
|
|
|
elif typefield == 'password':
|
|
|
if received_password is not None:
|
|
|
temp_row.append(received_password)
|
|
|
else:
|
|
|
temp_row.append(val)
|
|
|
obj_body.append(temp_row)
|
|
|
|
|
|
if not obj_body:
|
|
|
obj_body = [[None]]
|
|
|
return listToArrayArray(client, obj_body)
|
|
|
|
|
|
|
|
|
def collect_obj_body(body, field):
|
|
|
field = FieldAdapter.from_detect(field)
|
|
|
column = len(field.tablevalue.head)
|
|
|
result_table = []
|
|
|
choice_value = field.tablevalue.values
|
|
|
for i in range(len(body)):
|
|
|
temp_row = []
|
|
|
for j in range(column):
|
|
|
# not adding if readonly
|
|
|
if j > (len(choice_value) + 1):
|
|
|
continue
|
|
|
typefield = choice_value[j].typefield
|
|
|
if typefield == 'readonly' and j > 0:
|
|
|
continue
|
|
|
elif typefield in ['check', 'check_tristate']:
|
|
|
if len(body[i]) < j + 1:
|
|
|
temp_row.append('')
|
|
|
continue
|
|
|
if not body[i][j]:
|
|
|
temp_row.append('')
|
|
|
elif body[i][j].lower() in ['on', 'yes']:
|
|
|
temp_row.append('on')
|
|
|
elif body[i][j].lower() in ['off', 'no']:
|
|
|
temp_row.append('off')
|
|
|
else:
|
|
|
temp_row.append(body[i][j])
|
|
|
|
|
|
elif typefield in ['input', 'combo', 'comboEdit', 'openfile',
|
|
|
'file', 'password', 'radio', 'text']:
|
|
|
if len(body[i]) < j + 1:
|
|
|
temp_row.append('')
|
|
|
elif not body[i][j]:
|
|
|
temp_row.append('')
|
|
|
else:
|
|
|
temp_row.append(body[i][j])
|
|
|
elif typefield in ['multichoice', 'multichoice_add']:
|
|
|
if len(body[i]) < j + 1:
|
|
|
temp_row.append('')
|
|
|
elif not body[i][j]:
|
|
|
temp_row.append('')
|
|
|
else:
|
|
|
temp_row.append(body[i][j])
|
|
|
result_table.append(temp_row)
|
|
|
return result_table
|
|
|
|
|
|
|
|
|
def getErrorOnParam(args, field):
|
|
|
"""
|
|
|
Get errors for param
|
|
|
"""
|
|
|
params_text = ""
|
|
|
if any("-" in x for x in (y for y in (field.opt.longopt, field.opt.shortopt) if y)):
|
|
|
param_name = ', '.join((x for x in [field.opt.shortopt, field.opt.longopt] if x))
|
|
|
else:
|
|
|
param_name = field.opt.metavalue
|
|
|
if getattr(args, field.name) is None and "need" not in field.type:
|
|
|
params_text += "%s. " + _("Use the parameter") + " "
|
|
|
params_text += param_name + '. '
|
|
|
else:
|
|
|
if "need" in field.type:
|
|
|
params_text += \
|
|
|
_('Error in field \'%s\'. ') % field.label + " %s"
|
|
|
elif getattr(args, field.name) == "list" and "choice" in field.type:
|
|
|
params_text += "%s"
|
|
|
else:
|
|
|
params_text += _('Error in parameter ')
|
|
|
params_text += param_name + '. %s'
|
|
|
return params_text
|