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-core/core/server/api_types.py

494 lines
18 KiB

#!/usr/bin/python
#-*- coding: utf-8 -*-
# Copyright 2012 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.
from soaplib.serializers.primitive import String, Integer, Boolean, Any
from soaplib.serializers.clazz import Array, ClassSerializer
from soaplib.service import rpc
import sys
from itertools import *
from calculate.lib.datavars import SourceReadonlyVariable
from calculate.lib.cl_lang import setLocalTranslate
setLocalTranslate('cl_core',sys.modules[__name__])
################# API ########################
class DataVarsSerializer(ClassSerializer):
"""Serializer for datavars types"""
def elementByType(self,typeobj):
"""Get element by variable type, given for table or not"""
elementMap = {'table':'table',
"string":"input",
"bool":"check",
"boolauto":"check_tristate",
"choice":"combo",
"choiceedit":"comboEdit",
"choiceedit-list":"multichoice_add",
"choice-list":"multichoice",
"bool-list":"multichoice",
"list":"multichoice_add",
"password":"password"}
return elementMap.get(typeobj,'input')
def arrayString(self,value):
if type(value) in (list,tuple):
return [""]+list(value)
else:
return value
def arrayArrayString(self,value):
if type(value) in (list,tuple):
return map(self.arrayString,value)
else:
return value
def getChoice(self,varObj):
if "choice" in varObj.type or "file" in varObj.type:
choice,comments = varObj.parent.ChoiceAndComments(varObj.name)
return self.arrayString(choice),self.arrayString(comments)
else:
return (None,None)
class ChoiceValue(DataVarsSerializer):
typefield = String
values = Array(String)
comments = Array(String)
onChanged = Array(String)
def __init__(self,dv=None,varObj=None,readOnly=False,**kwargs):
if dv:
super(ChoiceValue,self).__init__()
if not readOnly:
self.values, self.comments = self.getChoice(varObj)
elif isinstance(varObj,SourceReadonlyVariable):
self.values, self.comments = \
zip(*varObj.getMapHumanReadable().items())
self.values = self.arrayString(self.values)
self.comments = self.arrayString(self.comments)
if varObj.mode == 'w':
self.typefield = varObj.element or \
self.elementByType(varObj.type)
else:
if readOnly:
self.typefield = "readonly"
else:
self.typefield = "text"
else:
super(ChoiceValue,self).__init__(**kwargs)
def elementByType(self,typeobj):
"""Get element by variable type, given for table or not"""
return DataVarsSerializer.elementByType(self,
typeobj.replace("-list","").replace("list",""))
class Table(DataVarsSerializer):
head = Array(String)
fields = Array(String) # name fields in params object
body = Array(Array(String))
values = Array(ChoiceValue)
onClick = String
addAction = String
def __init__(self,dv=None,varObj=None,head=None,body=None,values=None,
fields=None,onClick=None,addAction=None):
super(Table,self).__init__()
if dv:
self.head = []
self.body = []
self.values = []
# get information about all table columns
self.writable = True
for i,col in enumerate(varObj.source):
# get columns variable obj
varSource = dv.getInfo(col)
# invalidate columns vars for uncompatible table
if varSource.uncompatible():
dv.Invalidate(col,onlySet=True)
# header label
self.head.append(varSource.label or varSource.name)
# if column writable then add ChoiceValue info
if varSource.mode == 'w' or i == 0:
self.values.append(ChoiceValue(dv,varSource))
if varSource.mode == 'r' and i == 0:
self.writable = False
else:
self.values.append(ChoiceValue(dv,varSource,readOnly=True))
# get table body
# empty value at start add for fix data transfer
self.body = self.arrayArrayString(dv.Get(varObj.name,
humanreadable=None))
else:
self.head = head
self.fields = fields
self.body = body
self.values = values
self.onClick = onClick
self.addAction = addAction
class Option(DataVarsSerializer):
shortopt = String
longopt = String
metavalue = String
help = String
def __init__(self,optlist,metaval,helpval):
super(Option,self).__init__()
self.help = helpval
self.metavalue = metaval
for val in optlist:
if val.startswith('--'):
self.longopt=val
else:
self.shortopt=val
class Field(DataVarsSerializer):
name = String # varname from Datavars
label = String # label for GUI
type = String # data type of variable
opt = Option # opt for cmdline
help = String # help for cmdline (GUI?)
element = String # type element
choice = Array(String) # value (combobox,comboedit)
listvalue = Array(String) # current listvalue
default = Boolean # default value or False
value = String # current value
tablevalue = Table # current table value
uncompatible = String # message for uncompatibility variable
comments = Array(String) # comments for choice
def __init__(self,dv=None,varObj=None,expert=False,briefmode=False,
inbrief=False,groupVars=(),**kwargs):
"""
dv - datavars, varObj - current variable, expert - expert variable flag,
briefmode - view request for brief, inbrief - variable palced in brief,
"""
if dv:
super(Field,self).__init__()
self.name = varObj.name
self.label = varObj.label or varObj.name
self.type = varObj.type
if varObj.opt:
self.opt = Option(varObj.opt,varObj.metavalue,varObj.help)
self.help = varObj.help
self.element = varObj.element or \
self.elementByType(self.type)
if inbrief:
self.uncompatible = ""
else:
self.uncompatible = dv.Uncompatible(varObj.name)
if self.uncompatible:
for var in varObj.reqUncompat:
if not briefmode and var in groupVars:
if not dv.Uncompatible(var.name):
self.uncompatible = ""
break
else:
dv.Invalidate(varObj.name,onlySet=True)
if expert:
self.default = not varObj.wasSet
self.choice, self.comments = self.getChoice(varObj)
if self.type == "table":
self.tablevalue = Table(dv=dv,varObj=varObj)
if self.tablevalue.writable:
self.type = "writable"
else:
value = dv.Get(varObj.name)
if type(value) == list:
self.listvalue = self.arrayString(value)
else:
if briefmode and not "choice" in self.type:
self.value = dv.Get(varObj.name,humanreadable=True)
else:
self.value = value
#if self.value:
# self.default = self.value
else:
super(Field,self).__init__(**kwargs)
class GroupField(DataVarsSerializer):
name = String
fields = Array(Field)
prevlabel = String
nextlabel = String
prevlabel = String
last = Boolean
def __init__(self,name="",fields=[],prevlabel="",
nextlabel="",last=False,dv=None,info=None,
expert=False,brief=False):
super(GroupField,self).__init__()
self.last = last
if dv:
self.name = info['name']
self.nextlabel = info['next_label']
self.prevlabel = _("Previous")
self.fields = []
# get all variables with deps which using in this group
groupDepVars = []
for varname in chain(info['normal'],info['expert']):
for var in dv.getRequired(varname):
if not var in groupDepVars:
groupDepVars.append(var)
for varname in info['normal']:
inbrief = brief and varname in info['brief']
varObj = dv.getInfo(varname)
self.fields.append(Field(dv=dv,inbrief=inbrief,
briefmode = brief,
varObj=varObj,
groupVars=groupDepVars))
if info['expert']:
for varname in info['expert']:
if expert == True or \
expert == None and dv.getInfo(varname).wasSet:
self.fields.append(Field(name = "expert",
element = "expert",
label=info['expert_label'],
value="open"))
for varname in info['expert']:
inbrief = brief and varname in info['brief']
varObj = dv.getInfo(varname)
self.fields.append(Field(dv=dv,expert=True,
inbrief=inbrief,
briefmode = brief,
varObj=varObj,
groupVars=groupDepVars))
break
else:
if expert == False:
for varname in info['expert']:
dv.Invalidate(varname,True)
self.fields.append(Field(name = "expert",
element = "expert",
label=info['expert_label'],
value="close"))
else:
self.name = name
self.fields = fields
self.nextlabel = nextlabel
class ViewInfo(DataVarsSerializer):
groups = Array(GroupField)
def __init__(self,datavars=None,step=None,expert=None,allsteps=False,
brief=None,brief_label=None,groups=[]):
super(ViewInfo,self).__init__()
if datavars:
self.groups = []
varGroups = datavars.getGroups()
lastGroup = len(varGroups)-1
# interate all vars group
if step in(0,-1,None) or allsteps:
briefData = datavars.getBrief()
self.groups.append(self.stepGroup(varGroups,brief_label,
help_value=briefData.get("help",None),
next_value=briefData.get("next",None)))
for i, groupInfo in enumerate(varGroups):
if step in (None,-1) or step == i:
self.groups.append(GroupField(dv=datavars,info=groupInfo,
last=(lastGroup==i),expert=expert,
brief=brief))
else:
self.groups = groups
def stepGroup(self,groupInfo,brief_label,help_value=None,next_value=None):
"""Step group"""
return GroupField(fields=[
Field(name = "Steps",
element = "table",
label = brief_label,
type = 'steps',
help = help_value,
value = next_value,
tablevalue = Table(
head = [i['name'] for i in groupInfo],
body = [list(i['normal'])+[""]+list(i['expert'])
for i in groupInfo]))])
#element = ['table', 'radio', 'combo', 'comboEdit', 'multichoice', \
#'multichoice_add', 'check', 'check_tristate', 'expert', 'input']
class ViewParams(ClassSerializer):
"""
Struct for _view methods
"""
step = Integer # number of group variables
expert = Boolean # request expert variables
brief = Boolean # request brief variables
################# MESSAGE ####################
class ReturnedMessage(ClassSerializer):
type = String
field = String
message = String
expert = Boolean
def __init__(self, type = None, field = None, message = None,
expert = False):
self.type = type
self.field = field
self.message = message
self.expert = expert
class Message(ClassSerializer):
type = String
message = String
id = Integer
def __init__(self, type = 'normal', message = None, id = None):
self.type = type
self.message = message
self.id = id
class ReturnProgress(ClassSerializer):
percent = Integer
short_message = String
long_message = String
def __init__(self, percent, short_message = None, long_message = None):
self.percent = percent
self.short_message = short_message
self.long_message = long_message
class Frame(ClassSerializer):
values = Array (Message)
from decorators import Dec
import pickle, os
# get and send client messages
class ApiWsdl:
perm_denied = []
perm_denied.append(Message (type = 'error', message = '403 Forbidden'))
# verification of compliance certificate and process (pid)
def check_cert_pid (self, sid, pid):
import threading
curThread = threading.currentThread()
cert = curThread.client_cert
from cert_cmd import find_cert_id
cert_id = find_cert_id(cert, self.data_path, self.certbase)
cert_id = int(cert_id)
if cert_id == 0:
return 0
# session file
if not os.path.exists(self.sids):
os.system('mkdir %s' %self.sids)
check = 0
fd = open(self.sids_file, 'r')
while 1:
try:
# read all on one record
list_sid = pickle.load(fd)
except:
break
# find session id in sids file
if cert_id == list_sid[1]:
if sid == list_sid[0]:
check = 1
if check == 0:
return 0
fd = open(self.sids_pids, 'r')
while 1:
try:
#read out on 1 record
list_pid = pickle.load(fd)
except:
break
if sid == list_pid[0]:
if pid == list_pid[1]:
fd.close()
return 1
fd.close()
return 0
# send to client all new message
def process_messages (self, pid):
result = []
while len(self.glob_frame_list[pid]) > \
self.glob_process_dict[pid]['counter']:
item = self.glob_process_dict[pid]['counter']
result.append(self.glob_frame_list[pid][item])
self.glob_process_dict[pid]['counter'] += 1
return result
# send to client new message from frame
def client_get_frame(self, sid, pid):
if self.check_cert_pid(sid, pid):
return self.process_messages(pid)
return self.perm_denied
# send to client new message from frame
def client_get_entire_frame(self, sid, pid):
if self.check_cert_pid(sid, pid):
try:
results = self.glob_frame_list[pid]
except:
return self.perm_denied
self.glob_process_dict[pid]['counter'] = \
len(self.glob_frame_list[pid])
return results
return self.perm_denied
def client_get_table (self, sid, pid, id):
if self.check_cert_pid(sid, pid):
return self.glob_table_dict[pid][id]
return self.perm_denied
def client_get_progress (self, sid, pid, id):
if self.check_cert_pid(sid, pid):
return self.glob_progress_dict[pid][id]
return self.perm_denied
# get message from client
def client_send_message(self, sid, pid, text):
if self.check_cert_pid(sid, pid):
self.glob_process_dict[pid]['answer'] = text
return Message (type = 'normal', message = "Password send")
return self.perm_denied
@rpc(Integer, Integer, _returns = Array(Message))
#@Dec.check_permissions()
def get_frame (self, sid, pid):
return self.client_get_frame (sid, pid)
@rpc(Integer, Integer, _returns = Array(Message))
def get_entire_frame(self, sid, pid):
return self.client_get_entire_frame (sid, pid)
@rpc(Integer, Integer, Integer, _returns = ReturnProgress)
#@Dec.check_permissions()
def get_progress ( self, sid, pid, id):
return self.client_get_progress (sid, pid, id)
@rpc(Integer, Integer, Integer, _returns = Table)
#@Dec.check_permissions()
def get_table ( self, sid, pid, id):
return self.client_get_table (sid, pid, id)
# get messages, transferred from client
@rpc(Integer, Integer, String, _returns = Message)
#@Dec.check_permissions()
def send_message ( self, sid, pid, text):
return self.client_send_message (sid, pid, text)