예제 #1
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)
예제 #2
0
    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