def format(self, seg_term=None, ele_term=None, subele_term=None): """ @rtype: string @raise EngineError: If a terminator is None and no default """ if seg_term is None: seg_term = self.seg_term if ele_term is None: ele_term = self.ele_term if subele_term is None: subele_term = self.subele_term if seg_term is None: raise EngineError('seg_term is None') if ele_term is None: raise EngineError('ele_term is None') if subele_term is None: raise EngineError('subele_term is None') str_elems = [] # get index of last non-empty element i = 0 for i in range(len(self.elements) - 1, -1, -1): if not self.elements[i].is_empty(): break for ele in self.elements[:i + 1]: str_elems.append(ele.format(subele_term)) return '%s%s%s%s' % (self.seg_id, ele_term, ele_term.join(str_elems), seg_term)
def seg(self, seg_node, seg_data): """ Generate XML for the segment data and matching map node @param seg_node: Map Node @type seg_node: L{node<map_if.x12_node>} @param seg_data: Segment object @type seg_data: L{segment<segment.Segment>} """ if not seg_node.is_segment(): raise EngineError('Node must be a segment') parent = pop_to_parent_loop(seg_node) # Get enclosing loop # check path for new loops to be added cur_path = self._path_list(parent.get_path()) if self.last_path != cur_path: last_path = self.last_path match_idx = self._get_path_match_idx(last_path, cur_path) root_path = self._path_list( os.path.commonprefix(['/'.join(cur_path), '/'.join(last_path)])) if seg_node.is_first_seg_in_loop() and root_path == cur_path: match_idx -= 1 for i in range(len(last_path) - 1, match_idx - 1, -1): self.writer.pop() for i in range(match_idx, len(cur_path)): (xname, attrib) = self._get_loop_info(cur_path[i]) self.writer.push(xname, attrib) seg_node_id = self._get_node_id(seg_node, parent, seg_data) (xname, attrib) = self._get_seg_info(seg_node_id) self.writer.push(xname, attrib) for i in range(len(seg_data)): child_node = seg_node.get_child_node_by_idx(i) if child_node.usage == 'N' or seg_data.get('%02i' % (i + 1)).is_empty(): pass # Do not try to ouput for invalid or empty elements elif child_node.is_composite(): (xname, attrib) = self._get_comp_info(seg_node_id) self.writer.push(xname, attrib) comp_data = seg_data.get('%02i' % (i + 1)) for j in range(len(comp_data)): subele_node = child_node.get_child_node_by_idx(j) (xname, attrib) = self._get_subele_info(subele_node.id) self.writer.elem(xname, comp_data[j].get_value(), attrib) self.writer.pop() # end composite elif child_node.is_element(): if seg_data.get_value('%02i' % (i + 1)) == '': pass #self.writer.empty(u"ele", attrs={u'id': child_node.id}) else: (xname, attrib) = self._get_ele_info(child_node.id) self.writer.elem(xname, seg_data.get_value('%02i' % (i + 1)), attrib) else: raise EngineError( 'Node must be a either an element or a composite') self.writer.pop() # end segment self.last_path = cur_path
def get_by_elem_num(self, ele_num): """ Get the element characteristics for the indexed element code @param ele_num: the data element code @type ele_num: string @return: {data_type, min_len, max_len, name} @rtype: dict """ if not ele_num: raise EngineError('Bad data element %s' % (ele_num)) if ele_num not in self.dataele: raise EngineError('Data Element "%s" is not defined' % (ele_num)) return self.dataele[ele_num]
def not_match_re(short_data_type, val, charset='B', icvn='00401'): """ @param short_data_type: simplified data type @type short_data_type: string @param val: data value to be verified @type val: string @param charset: [optional] - 'B' for Basic X12 character set, 'E' for extended, E5 for 5010 Extended @type charset: string @return: True if found invalid characters, False if none @rtype: boolean """ if short_data_type in ('ID', 'AN'): if charset == 'E': # extended charset if icvn == '00501': rec = rec_ID_E5 else: rec = rec_ID_E elif charset == 'B': # basic charset: rec = rec_ID_B elif short_data_type == 'DT': rec = rec_DT elif short_data_type == 'TM': rec = rec_TM else: raise EngineError('Unknown data type %s' % (short_data_type)) m = rec.search(val) if m and m.group(0): return True # Invalid char matched return False
def __init__(self, xml_out=None, basedir=None): """ @param xml_out: Output filename, if None, will dump to tempfile @param basedir: working directory, where file will be created """ if xml_out: self.filename = xml_out fd = open(xml_out, 'w') else: try: (fdesc, self.filename) = tempfile.mkstemp('.xml', 'pyx12_') fd = os.fdopen(fdesc, 'w+b') #fd = tempfile.NamedTemporaryFile() #self.filename = fd.name except: #self.filename = '997.tmp.xml' (fdesc, self.filename) = tempfile.mkstemp(suffix='.xml', prefix='pyx12_', dir=basedir) fd = os.fdopen(fdesc, 'w+b') #fd = file(os.path.join(basedir, self.filename), 'w') self.cur_line = None self.errors = [] if not fd: raise EngineError('Could not open temp error xml file') self.writer = XMLWriter(fd) #self.writer.doctype( # u"x12simple", u"-//J Holland//DTD XML X12 Document # Conversion1.0//EN//XML", # u"%s" % (dtd_urn)) self.writer.push("x12err")
def _read_config_file(self, filename): """ Read program configuration from an XML file @param filename: XML file @type filename: string @raise EngineError: If the config file is not found or is unreadable @return: None """ if not isfile(filename): self.logger.debug('Configuration file "%s" does not exist' % filename) raise EngineError('Configuration file "%s" does not exist' % (filename)) try: self.logger.debug('parsing config file %s' % (filename)) t = et.parse(filename) for c in t.iter('param'): option = c.get('name') value = c.findtext('value') valtype = c.findtext('type') self._set_option(option, value, valtype) except Exception: self.logger.error('Read of configuration file "%s" failed' % (filename)) raise
def __init__(self, ele_str, subele_term=None): """ @type ele_str: string @raise EngineError: If a terminator is None and no default """ if subele_term is None or len(subele_term) != 1: raise EngineError( 'The sub-element terminator must be a single character, is %s' % (subele_term)) self.subele_term = subele_term self.subele_term_orig = subele_term if ele_str is None: raise EngineError('Element string is None') members = ele_str.split(self.subele_term) self.elements = [] for elem in members: self.elements.append(Element(elem))
def pop_to_parent_loop(node): """ @param node: Loop Node @type node: L{node<map_if.x12_node>} @return: Closest parent loop node @rtype: L{node<map_if.x12_node>} """ if node.is_map_root(): return node map_node = node.parent if map_node is None: raise EngineError("Node is None: %s" % (node.name)) while not (map_node.is_loop() or map_node.is_map_root()): map_node = map_node.parent if not (map_node.is_loop() or map_node.is_map_root()): raise EngineError("Called pop_to_parent_loop, can't find parent loop") return map_node
def visit_st_pre(self, err_st): """ @param err_st: ST Loop error handler @type err_st: L{error_handler.err_st} """ if err_st is None: raise EngineError('Cannot create AK2 : err_st is None') if err_st.trn_set_id is None: raise EngineError('Cannot create AK2: err_st.trn_set_id was not set') if err_st.trn_set_control_num is None: raise EngineError('Cannot create AK2: err_st.trn_set_control_num was not set') if err_st.vriic is None: raise EngineError('Cannot create AK2: err_st.vriic was not set') seg_data = pyx12.segment.Segment('AK2', '~', '*', ':') seg_data.set('01', err_st.trn_set_id) seg_data.set('02', err_st.trn_set_control_num.strip()) seg_data.set('03', err_st.vriic) self.wr.Write(seg_data)
def visit_st_post(self, err_st): """ @param err_st: ST Loop error handler @type err_st: L{error_handler.err_st} """ if err_st.ack_code is None: raise EngineError('err_st.ack_cde variable not set') seg_data = pyx12.segment.Segment('IK5', '~', '*', ':') seg_data.set('01', err_st.ack_code) err_codes = self.__get_st_errors(err_st) for err_code in err_codes[:5]: seg_data.append(err_code) self.wr.Write(seg_data)
def __init__(self, err_cde, err_str, ele_idx, subele_idx=None, err_val=None): ErrorItem.__init__(self, 'ele', err_cde, err_str) self.err_val = err_val self.ele_idx = ele_idx self.subele_idx = subele_idx if self.err_cde not in ele_errors: raise EngineError('Invalid element level error code "%s"' % (self.err_cde))
def isValid(self, key, code, check_dte=None): """ Is the code in the list identified by key @param key: the external codeset identifier @type key: string @param code: code to be verified @type code: string @param check_dte: deprecated @type check_dte: string @return: True if code is valid, False if not @rtype: boolean """ #if not given a key, do not flag an error if not key: raise EngineError('bad key %s' % (key)) #check the code against the list indexed by key else: if key in self.exclude_list: return True if key not in self.codes: raise EngineError('External Code "%s" is not defined' % (key)) if code in self.codes[key]['codes']: return True return False
def format(self, subele_term=None): """ Format a composite @return: string @raise EngineError: If terminator is None and no default """ if subele_term is None: subele_term = self.subele_term if subele_term is None: raise EngineError('subele_term is None') for i in range(len(self.elements) - 1, -1, -1): if not self.elements[i].is_empty(): break return subele_term.join( [Element.__repr__(x) for x in self.elements[:i + 1]])
def visit_st_post(self, err_st): """ @param err_st: ST Loop error handler @type err_st: L{error_handler.err_st} """ if err_st.ack_code is None: raise EngineError('err_st.ack_cde variable not set') # self.ack_code = None # AK501 seg_data = pyx12.segment.Segment('AK5', '~', '*', ':') # self.err_cde = [] # AK502-6 #seg.append(err_st.ack_code) seg_data.append(err_st.ack_code) err_codes = self.__get_st_errors(err_st) for i in range(min(len(err_codes), 5)): seg_data.append(err_codes[i]) #seg.append(err_codes[i]) self._write(seg_data)
def seg_context(self, seg_node, seg_data, pop_loops, push_loops): """ Generate XML for the segment data and matching map node @param seg_node: Map Node @type seg_node: L{node<map_if.x12_node>} @param seg_data: Segment object @type seg_data: L{segment<segment.Segment>} """ assert seg_node.is_segment(), 'Node must be a segment' parent = pop_to_parent_loop(seg_node) # Get enclosing loop for loop in pop_loops: self.writer.pop() for loop in push_loops: (xname, attrib) = self._get_loop_info(loop.id) self.writer.push(xname, attrib) (xname, attrib) = self._get_seg_info(seg_node.id) self.writer.push(xname, attrib) for i in range(len(seg_data)): child_node = seg_node.get_child_node_by_idx(i) if child_node.usage == 'N' or seg_data.get('%02i' % (i + 1)).is_empty(): pass # Do not try to ouput for invalid or empty elements elif child_node.is_composite(): (xname, attrib) = self._get_comp_info(seg_node.id) self.writer.push(xname, attrib) comp_data = seg_data.get('%02i' % (i + 1)) for j in range(len(comp_data)): subele_node = child_node.get_child_node_by_idx(j) (xname, attrib) = self._get_subele_info(subele_node.id) self.writer.elem(xname, comp_data[j].get_value(), attrib) self.writer.pop() # end composite elif child_node.is_element(): if seg_data.get_value('%02i' % (i + 1)) == '': pass #self.writer.empty(u"ele", attrs={u'id': child_node.id}) else: (xname, attrib) = self._get_ele_info(child_node.id) self.writer.elem(xname, seg_data.get_value('%02i' % (i + 1)), attrib) else: raise EngineError( 'Node must be a either an element or a composite') self.writer.pop() # end segment
def match_re(short_data_type, val): """ @param short_data_type: simplified data type @type short_data_type: string @param val: data value to be verified @type val: string @return: True if matched, False if not @rtype: boolean """ if short_data_type == 'N': rec = rec_N elif short_data_type == 'R': rec = rec_R else: raise EngineError('Unknown data type %s' % (short_data_type)) m = rec.search(val) if not m: return False if m.group(0) != val: # matched substring != original, bad return False # nothing matched return True
def _parse_refdes(self, ref_des): """ Format of ref_des: - a simple element: TST02 - a composite: TST03 where TST03 is a composite - a sub-element: TST03-2 - or any of the above with the segment ID omitted (02, 03, 03-1) @param ref_des: X12 Reference Designator @type ref_des: string @rtype: tuple(ele_idx, subele_idx) @raise EngineError: If the given ref_des does not match the segment ID or if the indexes are not valid integers """ xp = pyx12.path.X12Path(ref_des) if xp.seg_id is not None and xp.seg_id != self.seg_id: err_str = 'Invalid Reference Designator: %s, seg_id: %s' \ % (ref_des, self.seg_id) raise EngineError(err_str) ele_idx = xp.ele_idx - 1 if xp.ele_idx is not None else None comp_idx = xp.subele_idx - 1 if xp.subele_idx is not None else None return (ele_idx, comp_idx)
def __init__(self, err_cde, err_str): ErrorItem.__init__(self, 'isa', err_cde, err_str) if self.err_cde not in isa_errors: raise EngineError('Invalid ISA level error code "%s"' % (self.err_cde))
def __init__(self, err_cde, err_str, err_val=None): ErrorItem.__init__(self, 'seg', err_cde, err_str) self.err_val = err_val if self.err_cde not in seg_errors: raise EngineError('Invalid segment level error code "%s"' % (self.err_cde))