class FindCases(FlowCommand): ''' Returns all uids of Nodes under the uid 'under' having a type 'type_name' and a case matching every clauses in the 'where' dict. The 'where' dict may be like: { 'some_param': 'The value to have', 'child.param': True, 'other_param': ('acceptable', 'values'), } ''' type_name=Arg() under = Arg() where=Arg() sub_paths=Arg() def doit(self): under = self.app.get_node(self.under or []) # default is root node uids = under.find(self.type_name, sub_paths=self.sub_paths, **self.where or {}) #print '------- FIND UNDER ROOT', self.type_name #for uid in uids: # print uid return uids
class GetNodeRelations(FlowCommand): ''' Returns a mapping {relation_type_name: relation_name}. If the Arg 'child_nodes' is not True, the ChildNode relations are excluded from the returned mapping. ''' node_id=Arg() child_nodes=Arg() proc_nodes=Arg() def doit(self): node_type = self.app.get_node_type(self.node_id) ret = collections.defaultdict(list) index_cmp = lambda a,b: cmp(a.index, b.index) for relation in sorted(node_type.iterrelations(), cmp=index_cmp): ret[relation.__class__.__name__].append((relation.name, relation.node_type.ui_infos())) if self.child_nodes: for relation in sorted(node_type.iterchildrelations(), cmp=index_cmp): ret['Child'].append((relation.name, relation.node_type.ui_infos())) if self.proc_nodes: for relation in sorted(node_type.iterprocrelations(), cmp=index_cmp): ret['Proc'].append((relation.name, relation.node_type.ui_infos())) return dict(ret)
class ProcExec(FlowCommand): ''' Executes the ProcNode using the given context and worker. If worker_id is None and some features are required by the execution context, one is looked up. If worker_id is None and no features are required, the worker will be None. ''' proc_id = Arg() context = Arg() worker_id = Arg() def doit(self): proc_node = self.app.get_node(self.proc_id) context = proc_node.get_execution_context_from_dict(self.context) if self.worker_id is None: features = context.get_needed_features() print 'worker look up for features', features if features: worker = self.app.host.find_worker_featuring(features) else: worker = None else: worker = self.app.host.get_worker(self.worker_id) if worker is None: raise CommandError('Cannot find a worker with id %r'%(self.worker_id,)) if not worker.check_connected(): raise CommandError('The worker with id %r is not connected!'%(self.worker_id,)) return proc_node.execute(self.context, worker)
class GetClientCmd(Command): ''' Returns a dict depicting the given command for the given station_class. The dict is like: { cmd_id: <the id of the command>, path: <the path of the executable>, env: <the environment dict to use or None for inherited>, additional_env: <a dict of environment value to set>, } Only the command allowed to run on the client side can be returned. ''' station_class = Arg() cmd_id = Arg() def doit(self): client_cmd = self.app.get_client_cmd(self.station_class, self.cmd_id) if client_cmd is None: raise CmdIdError( 'Cannot find Client command with id %r for station class %r.' % (self.cmd_id, self.station_class)) # NB: we copy the dicts here to avoid external modifications: return { 'executable': client_cmd['executable'], 'env': client_cmd['env'] and dict(client_cmd['env']) or None, 'additional_env': dict(client_cmd['additional_env']), }
class SetParamValue(FlowCommand): ''' Sets the value of the given param. ''' param_id=Arg() value=Arg() def doit(self): param_name = self.param_id[-1][1:] node_id = self.param_id[:-1] node = self.app.get_node(node_id) node.get_param_value(param_name).set(self.value)
class GetCaseIds(FlowCommand): ''' Returns a list of case ids for the given relation in the given node ''' node_id=Arg() relation_name=Arg() def doit(self): node = self.app.get_node(self.node_id) relation = node.get_relation(self.relation_name) return relation.get_related_ids(node)
class GetKeysFor(Command): root_name = Arg() type_name = Arg() def doit(self): try: return self.app.get_root(self.root_name).get_keys_for( self.type_name) except Exception, err: traceback.print_exc() raise NamingCommandError( 'There was an error: %s\n(see the AppHost output for the trace.)' % (err, ))
class GetTypeUiInfos(FlowCommand): ''' Returns ui infos for the type of the given node id. If the extended command argument is True, more data are returned (doc...). ''' node_id=Arg() extended=Arg(True) def doit(self): node_type = self.app.get_node_type(self.node_id) infos = node_type.ui_infos() if self.extended: infos['doc'] = node_type.doc() return infos
class GetCaseAttributes(FlowCommand): ''' Return a list of possible attribute names for the given node type name. ''' type_name=Arg() under=Arg() def doit(self): under = self.app.get_node_type(self.under or ()) comp = lambda a, b: cmp(a.split('.'), b.split('.')) return sorted( under.collect_case_attributes(self.type_name), cmp=comp )
class AppendToUserData(Command): ''' Appends to the value of a key in a user data. If the key exists in the user data, it must be a list. If the key does not exists in the user data, an empty list is stored first. ''' login = Arg() data_id = Arg() value = Arg() def doit(self): if None in (self.login, self.data_id, self.key): raise CommandError( 'The command arguments "login" and "data_id" cannot be None.') self.app.append_to_user_data(self.login, self.data_id, self.value)
class PrepareProcExec(FlowCommand): ''' Returns execution context data describing the tasks to run to execute the given ProcNode. If the context argument is not None it must contain data used to pre-configure the returned context. ''' proc_id=Arg() context=Arg() def doit(self): proc_node = self.app.get_node(self.proc_id) context = proc_node.prepare(self.context) return context.to_dict()
class SysCmdRun(Command): ''' Executes the given command from the AppHost, with the given string argument. ''' cmd_id = Arg() args_str = Arg() def doit(self): cmd = self.app.get_host_cmd(self.cmd_id) if cmd is None: raise CmdIdError('Cannot find AppHost command with id %r' % (self.cmd_id, )) print '>> EXECUTING SYSTEM COMMAND ON APPHOST:' pprint.pprint(cmd) print '<<'
class GetClientCmdInfos(Command): ''' Retuns a dict like {group_name: [cmd_infos, cmd_infos]} where cmd_infos has the keys ['id', 'label', 'icon'] Only the command allowed to run on the client side are returned. The same command may appear once in each group. ''' station_class = Arg() def doit(self): ret = collections.defaultdict(list) for cmd_id, cmd in self.app.itercmds(self.station_class): if not cmd['client_exec']: continue for group in cmd['groups']: ret[group].append({ 'id': cmd_id, 'label': cmd['label'], 'icon': cmd['icon'] }) return dict(ret)
class GetParamValue(FlowCommand): ''' Returns the value of the given param. ''' param_id=Arg() def doit(self): param = self.app.get_param(self.param_id) return param.get()
class GetHistory(Command): ''' Returns a time ordered list of the revisions existing on the file. If the file is not under version control, None is returned. ''' filename = Arg() for_user = Arg() versions_only = Arg(True) def doit(self): history = self.app.get_file_history(self.filename, self.for_user, self.versions_only) if history is None: return None ret = [entry.to_dict() for entry in history] return ret
class GetPath(Command): ''' Returns the string path of the given naming config under the given root. ''' root_name = Arg() config = Arg() def doit(self): try: return self.app.get_root(self.root_name).to_config( self.config).path() except Exception, err: traceback.print_exc() raise NamingCommandError( 'There was an error: %s\n(see the AppHost output for the trace.)' % (err, ))
class CollectParams(FlowCommand): ''' Returns a list of param uid having at least one of the given tags in the given node and its children ''' node_id=Arg() tags=Arg() def doit(self): if self.node_id is None: raise CommandError('CollectParams argument "node_id" cannot be None.') node = self.app.get_node(self.node_id) try: uids = node.collect_params(*self.tags) except TypeError: raise CommandError('CollectParams argument "tags" must be iterable.') return uids
class GetParamUiInfos(FlowCommand): ''' Returns a list of param ui infos (a dict like {'editor':<str>, 'group':<str>, 'index':<int>}) If the 'param_name' argument is None, all params in the node are returned. ''' node_id=Arg() param_name=Arg() def doit(self): node = self.app.get_node(self.node_id) if isinstance(node, _CaseProducer): node = node.parent_node if self.param_name is None: ret = [ param.ui_infos(node) for param in node.iterparams() ] else: ret = [ node.get_param(self.param_name).ui_infos(node) ] return self.app.arrange_param_ui_infos(ret)
class GetUserData(Command): ''' Returns the user data (a dict) with the given id for the given login. If the data id does not exists, an empty dict is returned. If key is not None, only this key in the data is returned. If no such key exists in the data, the default value is returned. ''' login = Arg() data_id = Arg() key = Arg() default = Arg() def doit(self): data = self.app.get_user_data(self.login, self.data_id, {}) if self.key is None: return data return data.get(self.key, self.default)
class LoadAll(FlowCommand): ''' Recursively instantiates all the related node of the given one. If the given node_id is None, the root node is used. ''' node_id=Arg() def doit(self): node = self.app.get_node(self.node_id) node.load_related(depth=True)
class GetUserMail(Command): ''' Returns the mail defined for the given user or None if the user does not have a mail defined in the app settings. If the user was not found, None is returned. ''' login = Arg() def doit(self): user = self.app.get_user(self.login) return user and user.mail or None
class GetNodeTypeNames(FlowCommand): ''' Return a list of (type_name, icon) used under the 'under' uid. If the argument 'case_nodes_only' is True, only the node type used in a Many or One relation are returned (those are the node holding a Case) ''' case_nodes_only=Arg() under=Arg() def doit(self): under = self.app.get_node_type(self.under or ()) ret = under.collect_types( exclude_children=self.case_nodes_only, visit_children=True, ) return sorted( (node_type.type_name(), node_type.ICON_NAME) for node_type in ret )
class SetUserData(Command): ''' Sets the value of a key in a user data. If the key is None, the value will be set as the whole user data dict. If the key is not None but the value is None, the key is removed from the user data. ''' login = Arg() data_id = Arg() key = Arg() value = Arg() def doit(self): if None in (self.login, self.data_id): raise CommandError( 'The command arguments "login" and "data_id" cannot be None.') if self.key is None: self.app.set_user_data(self.login, self.data_id, self.value) else: self.app.set_user_data_key(self.login, self.data_id, self.key, self.value)
class GetTypeParamUiInfos(FlowCommand): ''' Returns a list of param ui infos for the type of the given node id. ''' node_id=Arg() def doit(self): node_type = self.app.get_node_type(self.node_id) ret = [ param.ui_infos() for param in node_type.iterparams() ] return self.app.arrange_param_ui_infos(ret)
class GetConfig(Command): ''' Returns the config of 'path' relative to the root path item named 'root_name'. If 'root_name' is None, the class of the 'STORE' root item is used to create a temporary root and use it here. ''' root_name = Arg() path = Arg() def doit(self): if self.root_name is not None: root = self.app.get_root(self.root_name) relative_to = root named_path = root / self.path else: root_path, path = self.path.split(self.app.store_class.SEP, 1) relative_to = self.app.store_class.from_name(root_path) named_path = relative_to / path return named_path.config(relative_to=relative_to)
class GetTypeProcUiInfos(FlowCommand): ''' Returns a list of related Proc ui infos for the type of the given node id. ''' node_id=Arg() def doit(self): node_type = self.app.get_node_type(self.node_id) index_cmp = lambda a,b: cmp(a.index, b.index) ret = [ (relation.name, relation.node_type.ui_infos()) for relation in sorted(node_type.iterprocrelations(), cmp=index_cmp) ] return ret
class DropNode(FlowCommand): ''' Drops this node from its parent so that next access to its uid will create a new instance. If called on the root node, nothing is done. ''' node_id=Arg() def doit(self): parent_uid = self.node_id[:-1] if not parent_uid: return parent = self.app.get_node(parent_uid) parent.drop_related(self.node_id[-1])
class GetWorkerCmdInfos(Command): ''' Returns a list like [cmd_infos, cmd_infos] where cmd_infos has the keys ['id', 'label', 'icon'] Only the command registered as worker for the given station_class are returned. ''' station_class = Arg() def doit(self): ret = [] for cmd_id, cmd in self.app.itercmds(self.station_class): if not cmd['is_worker']: continue ret.append({ 'id': cmd_id, 'label': cmd['label'], 'icon': cmd['icon'] }) return ret