def _format_and_validate(self, args):    
        # Unpack args, trim and clean, repack
        
        # Get action first for clarity of code here
        # TODO - expunge the magic string!
        action = OrgmCliController._trim_quotes(args['action'])                
        # Process all the data elements, values for fields in Elem, dynamically
        for elem in Elem.get_data_elems():
            elem_type = Elem.get_elem_type(elem)
            if elem_type == Elem.LIST_TYPE:
                # Must split() the two list element types, so the string becomes Py list
                # Trim single and double quotes from each element
                # NOTE: _trim_quotes() keeps args not passed as None and empty strings as empty, 
                #  which is *crucial* to logic of _run_cli_get_group_elem() below        
                args[elem] = [OrgmCliController._trim_quotes(t).strip() for t in args[elem].split(',')]        
            elif elem_type == Elem.TEXT_TYPE:
                args[elem] = OrgmCliController._trim_quotes(args[elem])
        # Process filename
        args[ActionArg.FILENAME] = OrgmCliController._trim_quotes(args[ActionArg.FILENAME])
    
        # Validation
        if action == Action.ADD and not args[Elem.TITLE]:
            raise OrganizemIllegalUsageException("'--add' action must include '--title' element and a value for title.")            
        elif (action == Action.SETCONF_DATA_FILE or action == Action.SETCONF_BAK_FILE) \
            and not args[ActionArg.FILENAME]:
            raise OrganizemIllegalUsageException("'--setconf_*' actions must include '--filename' element and a value for filename.")

        return (action, args)
    def convert_to_item(py_item):
        """Converts Item serialized to Python object form, dicts and lists, to YAML"""

        # The list of names of elements an Item must have for this version
        elem_names = Elem.get_optional_data_elems()
        # List of names of elements in the py_item
        py_elem_names = YamlItemConverter._get_py_item_elems(py_item)

        # Item must have title element, so check for that first
        title = YamlItemConverter._get_py_item_title(py_item, py_elem_names)

        # Handling dynamic list of kwargs to __init__(), so build string
        #  dynamically and make __init__() call an eval()
        init_call = []
        init_call.append("Item('%s', {" % title)
        # eval(x) where x is a multiline string literal fails on
        #  exception from scanning literal and finding an EOL in it
        # So, store the multiline string in this local List.  Put the
        #  note_vals[idx] into the string to be evaled.
        # And, yes, this is a pretty sweet hack
        note_vals = []
        # Algo:
        #  - Iterate the list of expected elements, item_elems
        #  - Test for matching elem in py_item passed in (which was loaded from data)
        #  - If found, add to kwargs list with py_item value for Item.__init__()
        #  - If not found, add to kwargs list with None value for Item.__init__()
        for elem_name in elem_names:
            if elem_name in py_elem_names:
                idx = py_elem_names.index(elem_name)
                py_elems = py_item[Elem.ROOT]
                py_elem_val = py_elems[idx][elem_name]
                py_elem_val = Elem.elem_init(elem_name, py_elem_val).escaped_str()
                if py_elem_val:
                    # Handle special case of multiline string value for Note elem
                    # See comment above where note_vals[] is declared
                    if Elem.get_elem_type(elem_name) == Elem.MULTILINE_TEXT_TYPE:
                        note_vals.append(py_elem_val)
                        val_idx = len(note_vals) - 1
                        init_call.append("'%s' : note_vals[%i], " % (elem_name, val_idx))
                    else:
                        init_call.append("'%s' : %s, " % (elem_name, py_elem_val))
                else:
                    init_call.append("'%s' : None, " % elem_name)
            else:
                init_call.append("'%s' : None, " % elem_name)
        init_call.append("})")
        init_call = "".join(init_call)

        item = eval(init_call)
        return item
Exemple #3
0
 def __init__(self, title, dict_of_elems=None): 
     # Store list of all elements in Item
     self._elems = Elem.get_elems()
     
     # Required elements are 'ROOT' and 'TITLE'
     # Set 'root' Item Element
     self.__setattr__('_' + Elem.ROOT, Elem.elem_init(Elem.ROOT, None))           
     # 'title' Element is required, set it first
     if not title:
         raise OrganizemIllegalDataFormatException("Cannot construct Item with null or empty title")
     title_obj = Elem.elem_init(Elem.TITLE, title)
     self.__setattr__('_' + Elem.TITLE, title_obj)
     self.__setattr__(Elem.TITLE, title_obj.val)
             
     # A little dirty, but not bad. Elem exposes method to get list of optional
     #  elements, with the assumption being client can call get_optional_data_elems() to
     #  get all elements and this to get only optional, so it can take care of
     #  required ones (statically, as here) and process optional ones dynamically
     opt_elems = Elem.get_optional_data_elems()        
     for elem in opt_elems:
         kwval = None
         elem_obj = None
         if dict_of_elems:
             if elem in dict_of_elems:
                 kwval = dict_of_elems[elem]
             elem_obj = Elem.elem_init(elem, kwval)
             # Private object str(), repr() used by Item str() and repr()
             self.__setattr__('_' + elem, elem_obj)
             # Public getter just returns obj.val, value for the element
             self.__setattr__(elem, elem_obj.val)
         else:
             self.__setattr__('_' + elem, Elem.elem_init(elem, None))
             self.__setattr__(elem, None)
 def _get_match(self, action, args):
     match_elem = None
     match_val = None
     if action == Action.FIND or action == Action.REMOVE:
         for elemkey in Elem.get_data_elems():
             if elemkey in args:
                 argval = args[elemkey]
                 if len(argval):
                     match_elem = elemkey
                     match_val = argval
                     break
         # Validate that we have match_elem and match_val if action requires them
         if match_elem is None or match_val is None:
             raise OrganizemIllegalUsageException("'--find and --remove must include an element (e.g. --title) and a value for that element.")                
     return (match_elem, match_val)
 def __init__(self):
     # This line is the whole reason for all this clumsy scaffolding -- build the group by
     #  enums dynamically from Elem fields, so that if we add new Elements to Item
     #  there is nothing to keep in synch here
     for elem in Elem.get_data_elems():
         self.__setattr__(self.PFX + elem.upper(), self.PFX.lower() + elem.lower())