You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-utils-3-console/console/application/function.py

612 lines
20 KiB

#-*- coding: utf-8 -*-
# Copyright 2012-2013 Calculate Ltd. 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 time, os, sys, re
from fcntl import ioctl
from array import array
import termios
import subprocess
from OpenSSL import crypto
import shlex
from calculate.lib.utils.colortext import get_terminal_print
from sudsds import MethodNotFound
from calculate.core.server.cert_cmd import getHwAddr, getIpLocal
from calculate.core.server.replace_class import printTable,Methods
from calculate.core.client.progressbar import Bar,Percentage,ETA,ProgressBar
from calculate.lib.cl_lang import setLocalTranslate
from calculate.lib.cl_print import color_print
setLocalTranslate('cl_console3',sys.modules[__name__])
from calculate.core.client.function import create_obj
green = '\033[32m * \033[0m'
red = '\033[31m * \033[0m'
class _color_print(color_print):
def _printSUCCESS(self, string, offsetL=0, printBR=True):
self.printSUCCESS(string.encode('utf-8'), offsetL, printBR)
colorPrint = _color_print()
def _print (*args):
print " ".join(map(lambda x:unicode(x).encode('utf-8'),args))
# get list of certificate and session id
def get_sid (SID_FILE):
if not os.path.exists(SID_FILE):
fi = open(SID_FILE, 'w')
fi.write('0')
fi.close()
sid = 0
else:
fi = open(SID_FILE, 'r')
sid = fi.read()
fi.close()
return sid
def clear ():
""" delete caching suds file """
try:
import glob
for filename in glob.glob("/tmp/suds/suds-*"):
#print "delete", filename
try:
os.unlink (filename)
except OSError, e:
_print (e.message)
except:
print _("Failed to clear the cache! ")
return 1
def get_ip_global():
import urllib2
strURL = 'http://api.wipmania.com/'
f = urllib2.urlopen(urllib2.Request(strURL))
response = f.read()
outerIP = response.split("<br>")[0]
f.close()
return outerIP
def get_ip_mac_type(client_type = None):
results = []
#try:
results.append ( getIpLocal() )
#except:
#results.append ('no_ip')
#try:
results.append ( getHwAddr())
#except:
#results.append ('no_mac')
if client_type:
results.append (client_type)
else:
results.append ('console')
return results
def print_brief_group(Fields, group_name):
print_group_flag = False
# if group_name:
# _print ('\b'+group_name)
uncompatible_count = 0
for field in Fields:
if field.uncompatible:
uncompatible_count += 1
continue
if field.element in ['input', 'openfile']:
value = field.value if field.value else ''
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint._printSUCCESS('%s: %s' %(field.label, value))
elif field.element in ['combo', 'comboEdit', 'radio', 'file']:
if hasattr (field.comments, 'string') and field.value in \
field.choice.string:
value = map(lambda x: field.comments.string[x] \
if len(field.comments.string) > x \
else field.choice.string[x],
map(lambda x: field.choice.string.index(x), \
[field.value]))
value = ', '.join(value)
else:
value = field.value if field.value else ''
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint._printSUCCESS('%s: %s' %(field.label, value))
elif field.element in ['multichoice', 'multichoice_add',\
'selecttable', 'selecttable_add']:
if hasattr (field.comments, 'string') and \
hasattr (field.listvalue, 'string'):
value = map(lambda x: field.comments.string[x] \
if len(field.comments.string) > x \
else field.choice.string[x],
map(lambda x: field.choice.string.index(x), \
field.listvalue.string))
value = ', '.join(value)
elif hasattr (field.listvalue, 'string'):
value = ', '.join(field.listvalue.string)
else:
value = field.value if field.value else ''
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint._printSUCCESS('%s: %s' %(field.label, value))
# elif field.element == 'label':
# print field.label
elif field.element == 'error':
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint.printERROR(field.label)
elif field.element in ['check', 'check_tristate']:
if field.value == 'on':
value = _('yes')
elif field.value == 'off':
value = _('no')
elif field.value == 'auto':
value = _('auto')
else:
value = field.value
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint._printSUCCESS('%s: %s' %(field.label, value))
elif field.element == 'table' and field.type != 'steps':
if hasattr (field.tablevalue.head, 'string'):
head = field.tablevalue.head.string
else: head = None
body = []
if hasattr (field.tablevalue.body, 'stringArray'):
for row in field.tablevalue.body.stringArray:
if hasattr(row, 'string'):
body.append(row.string)
else: body = [[]]
# if empty table
if not filter (None, map(lambda x: x, body)):
body = [['']*len(head)]
res = printTable(body, head)
sys.stdout.flush()
sys.stdout.write(res)
continue
ChoiceValue = field.tablevalue.values.ChoiceValue
for row in xrange(len(ChoiceValue)):
if ChoiceValue[row].typefield in ['check', 'check_tristate']:
for i in xrange(len(body)):
if body[i][row] == 'on':
body[i][row] = _('yes')
if body[i][row] == 'off':
body[i][row] = _('no')
if body[i][row] == 'auto':
body[i][row] = _('auto')
if ChoiceValue[row].typefield == 'password':
for i in xrange(len(body)):
if body[i][row]:
body[i][row] = '***'
data = []
for body_row in body:
data.append(map(lambda x: x if x else '', body_row))
if not print_group_flag:
_print ('\b'+group_name)
print_group_flag = True
colorPrint._printSUCCESS('%s: ' %(field.label))
res = printTable(data, head)
sys.stdout.write(res+"\n")
sys.stdout.flush()
else:
uncompatible_count += 1
# if uncompatible_count == len (Fields) and group_name:
# colorPrint._printSUCCESS(_('Not used'))
def print_brief(view, brief_label):
for Group in view.groups.GroupField:
if Group.name:
if not Group.fields:
continue
print_brief_group(Group.fields.Field, Group.name)
class switch(object):
def __init__(self, value):
self.value = value
self.fall = False
def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration
def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False
#################API FUNCTION###############################
def show_view(view):
return
print "+====== show view! ======+"
def show_table(table, item):
if item.message:
colorPrint._printSUCCESS(item.message)
head = table.head.string if hasattr (table.head, 'string') else None
data = []
for line in table.body[0]:
if hasattr (line, 'string'):
data.append(line.string)
res = printTable(data, head)
sys.stdout.write(res+"\n")
sys.stdout.flush()
def show_error(item):
if item.message:
for line in item.message.splitlines():
Methods().printERROR(line)
def show_warning(item):
if item.message:
for line in item.message.splitlines():
Methods().printWARNING(line)
def show_group(item):
if item.message:
for line in item.message.splitlines():
Methods().printSUCCESS(line)
def show_result(result):
pass
def startTask(item):
if item.message:
for line in item.message.splitlines():
Methods().printSUCCESS(line)
#colorPrint._printSUCCESS(line)
def endTask(item):
if item.result is None:
result = item.message
else:
result = item.result
methods = Methods()
methods.terminal_print.up(1)('\r')
Methods().displayResult(result)
def beginFrame(item):
pass
def endFrame(item):
pass
def startGroup(item):
if item.message:
Methods().startGroup(item.message)
def endGroup(item):
pass
def _create_obj(client, method):
try:
view_params = create_obj(client, method)
except MethodNotFound:
if method.endswith('_view'):
method = method[:-5]
_print (_('Method not found: ') + method)
raise Exception(1)
return view_params
def get_view_params(client, method, step = None, expert = None, brief = None,
onlyhelp = False):
view_params = _create_obj(client, method)
view_params.step = step
view_params.expert = expert
view_params.brief = brief
view_params.onlyhelp = onlyhelp
return view_params
def callView(client, item, sid):
return
_print ("\n",item.message)
try:
view_params = get_view_params(client, item.message, brief = True, \
expert = True)
view = client.service[0][item.message] (sid, view_params)
show_view(view)
except:
pass
#################MESSAGE####################################
def analysis(client, sid, s):
""" analysis of the bounced message method """
messages = s[0]
for mess in messages:
if mess.type == 'pid':
try:
pid = int(mess.message)
except:
show_error(_('the server sent PID = ') + pid)
return 1
get_messages(client, sid, pid)
elif mess.type == 'error':
show_error(mess)
elif mess.type == 'warning':
show_warning(mess)
def get_message(client, item, sid, pid):
""" get one message by its type """
for case in switch(item.type):
if case('normal'):
if item.message:
Methods().printSUCCESS(item.message)
return 1
if case('plain'):
if item.message:
Methods().printDefault(item.message)
return 1
if case('pre'):
if item.message:
Methods().printPre(item.message)
return 1
if case('choice'):
message, answers = item.message.split('|')
answers = map(lambda x: (x[0], x[1].strip(')')),
map(lambda x: x.split('('),
answers.split(',')))
answer = Methods().askChoice(message, answers)
client.service.send_message(sid, pid, answer)
return 1
if case('progress'):
if not client.no_progress:
get_Progress(client, sid, pid, item.id)
return 1
if case('error'):
show_error(item)
if item.message == "403 Forbidden":
return 0
return 1
if case('warning'):
show_warning(item)
return 1
if case('table'):
get_Table(client, sid, pid, item)
return 1
if case('group'):
show_group(client, sid, pid, item)
return 1
if case('question'):
send_Message(client, sid, pid, item)
return 1
if case('confirm'):
send_Confirm(client, sid, pid, item)
return 1
if case('password'):
send_Password(client, sid, pid, item)
return 1
if case('startTask'):
startTask(item)
return 1
if case('endTask'):
endTask(item)
return 1
if case('beginFrame'):
beginFrame(item)
return 1
if case('endFrame'):
endFrame(item)
return 0
if case('startGroup'):
startGroup(item)
return 1
if case('endGruop'):
endGroup(item)
return 1
if case('briefParams'):
callView(client, item, sid)
if case(): # default, could also just omit condition or 'if True'
return 1
def get_messages(client, sid, pid):
""" get frame in a separate thread """
#thread_messages = threading.Thread(target=get_Frame,\
#args = (client, sid, pid))
#thread_messages.start()
get_Frame(client, sid, pid)
def get_Frame(client, sid, pid):
""" get all messages, until type is not endFrame (or Error) """
end_frame = 1
while end_frame:
current_frame = client.service[0].get_frame(sid, pid, "console")
while current_frame in [None, [], ""]:
time.sleep(float(client.frame_period))
current_frame = client.service[0].get_frame(sid, pid, "console")
for item in current_frame[0]:
end_frame = get_message(client, item, sid, pid)
def get_entire_frame(client, pid):
""" get entire frame, from beginning (if client disconnected) """
sid = get_sid(client.SID_FILE)
list_pid = client.service.list_pid(sid = sid)
if hasattr (list_pid, 'integer'):
if not pid in list_pid.integer:
print \
_('The process does not exist or does not belong to your session')
end_frame = 1
while end_frame:
current_frame = client.service.get_entire_frame(sid, pid)
while current_frame in [None, [], ""]:
time.sleep(1)
current_frame = client.service.get_frame(sid, pid, "console")
for item in current_frame[0]:
end_frame = get_message(client, item, sid, pid)
def get_Progress(client, sid, pid, id):
widgets = ['', '', Bar(), '', Percentage(), ' ', ETA()]
pbar = ProgressBar(widgets=widgets, maxval=100)
pbar.start()
""" get progress for the current job """
returnProgr = client.service.get_progress(sid, pid, id)
temp_progress = -1
last_message = ''
percent = returnProgr.percent
try:
while percent <= 100 and percent >= 0:
if temp_progress != percent:
last_message = print_progressbar(returnProgr, pbar,
last_msg=last_message)
if percent == 100:
return
temp_progress = percent
else:
pbar.update(percent)
time.sleep(1)
returnProgr = client.service.get_progress(sid, pid, id)
percent = returnProgr.percent
if percent < 0:
pbar.update(0)
pbar.finish()
else:
pbar.update(100)
pbar.finish()
finally:
terminal_print = \
get_terminal_print(color_print().defaultPrint)
terminal_print.up(1).clear_line("")
#terminal_print.up(1)("")
def cout_progress(string):
h,w=array('h', ioctl(sys.stderr,termios.TIOCGWINSZ,'\0'*8))[:2]
sys.stdout.write('\r' + (' '*(w)))
sys.stdout.write('\r' + string)
sys.stdout.flush()
def cout(string):
sys.stdout.write(string)
sys.stdout.flush()
def print_progressbar(returnProgr, pbar, last_msg = None, error = False):
if returnProgr.long_message:
if last_msg != returnProgr.long_message:
colorPrint._printSUCCESS('%s\n' %returnProgr.long_message)
pbar.update(returnProgr.percent)
return returnProgr.long_message
elif returnProgr.short_message:
if last_msg != returnProgr.short_message:
colorPrint._printSUCCESS('%s\n' %returnProgr.short_message)
pbar.update(returnProgr.percent)
return returnProgr.short_message
else:
pbar.update(returnProgr.percent)
return last_msg
def print_progress(returnProgr, last_msg = None, error = False):
if error:
cout_progress (red + '\n'+_("Task error by %s") \
%str(0 - returnProgr.percent).rjust(5) + '%\n')
return ''
elif returnProgr.long_message:
if last_msg == returnProgr.long_message:
cout_progress('%s%%' %str(returnProgr.percent).rjust(5))
else:
if not last_msg:
cout_progress('')
else:
cout_progress('OK'.rjust(6) + '\n')
cout_progress(green + '%s %s%%' %(returnProgr.long_message, \
str(returnProgr.percent).rjust(5)))
return returnProgr.long_message
elif returnProgr.short_message:
if last_msg == returnProgr.short_message:
cout_progress('%s%%' %str(returnProgr.percent).rjust(5))
else:
if not last_msg:
cout_progress('')
else:
cout_progress('OK'.rjust(6) + '\n')
cout_progress(green + '%s %s%%' %(returnProgr.short_message, \
str(returnProgr.percent).rjust(5)))
return returnProgr.short_message
else:
# print '%s' %str(returnProgr.percent).rjust(5) + '%'
cout_progress ('%s' %str(returnProgr.percent).rjust(5) + '%')
return ''
def get_Table(client, sid, pid, item):
table = client.service.get_table(sid, pid, item.id)
show_table(table, item)
def send_Confirm(client,sid,pid,item):
ask = Methods().askConfirm(item.message, item.default or "")
client.service.send_message(sid, pid, ask)
def send_Message(client, sid, pid, item):
""" send answer to the question """
print
answer = raw_input (item.message)
client.service.send_message(sid, pid, answer)
# show_result(result)
def send_Password(client, sid, pid, item):
""" send password """
from getpass import getpass
password = getpass(prompt=item.message)
result = client.service.send_message(sid, pid, password)
show_result(result)
def _return_revoked_serials(self, crlfile):
try:
serials = []
crltext = open(crlfile, 'r').read()
crl = crypto.load_crl(crypto.FILETYPE_PEM, crltext)
revs = crl.get_revoked()
for revoked in revs:
serials.append(str(revoked.get_serial()))
return serials
except (ImportError, AttributeError):
call = '/usr/bin/openssl crl -text -noout -in %s' % crlfile
call = shlex.split(call)
serials = []
(res,err)=subprocess.Popen(call, stdout=subprocess.PIPE).communicate()
for line in res.split('\n'):
if line.find('Serial Number:') == -1:
continue
(crap, serial) = line.split(':')
serial = serial.strip()
serial = int(serial, 16)
serials.append(serial)
return serials