def from_segments(cls, segments: list or collections.Iterable) -> "Interchange": segments = iter(segments) first_segment = next(segments) if first_segment.tag == 'UNA': unb = next(segments) elif first_segment.tag == 'UNB': unb = first_segment else: raise EDISyntaxError( 'An interchange must start with UNB or UNA and UNB') # Loosy syntax check : if len(unb.elements) < 4: raise EDISyntaxError('Missing elements in UNB header') datetime_str = '-'.join(unb.elements[3]) timestamp = datetime.datetime.strptime(datetime_str, '%y%m%d-%H%M') interchange = Interchange( syntax_identifier=unb.elements[0], sender=unb.elements[1], recipient=unb.elements[2], timestamp=timestamp, control_reference=unb.elements[4], ) if first_segment.tag == 'UNA': interchange.has_una_segment = True interchange.characters = Characters.from_str( first_segment.elements[0]) return interchange.add_segments(segment for segment in segments if segment.tag != 'UNZ')
def from_segments(cls, segments: Union[list, Iterable]) -> "Interchange": segments = iter(segments) first_segment = next(segments) if first_segment.tag == "UNA": unb = next(segments) elif first_segment.tag == "UNB": unb = first_segment else: raise EDISyntaxError( "An interchange must start with UNB or UNA and UNB") # Loosy syntax check : if len(unb.elements) < 4: raise EDISyntaxError("Missing elements in UNB header") datetime_str = "-".join(unb.elements[3]) timestamp = datetime.datetime.strptime(datetime_str, "%y%m%d-%H%M") interchange = Interchange( syntax_identifier=unb.elements[0], sender=unb.elements[1], recipient=unb.elements[2], timestamp=timestamp, control_reference=unb.elements[4], ) if first_segment.tag == "UNA": interchange.has_una_segment = True interchange.characters = Characters.from_str( first_segment.elements[0]) return interchange.add_segments(segments)
def get_messages(self) -> List[Message]: message = None for segment in self.segments: if segment.tag == 'UNH': if not message: message = Message(segment.elements[0], segment.elements[1]) else: raise EDISyntaxError( f"Missing UNT segment before new UNH: {segment}") elif segment.tag == 'UNT': if message: yield message else: raise EDISyntaxError( f'UNT segment without matching UNH: "{segment}"') else: if message: message.add_segment(segment)
def create_segment(name: str, *elements: Union[str, List[str]], validate: bool = True) -> Segment: """Create a new instance of the relevant class type. :param name: The name of the segment :param elements: The data elements for this segment :param validate: bool if True, the created segment is validated before return """ if not SegmentFactory.characters: SegmentFactory.characters = Characters() # Basic segment type validation is done here. # The more special validation must be done in the corresponding Segment if not name: raise EDISyntaxError("The tag of a segment must not be empty.") if type(name) != str: raise EDISyntaxError( "The tag name of a segment must be a str, but is a {}: {}". format(type(name), name)) if not name.isalnum(): raise EDISyntaxError( "Tag '{}': A tag name must only contain alphanumeric characters." .format(name)) for Plugin in SegmentProvider.plugins: if Plugin().tag == name: s = Plugin(name, *elements) else: # we don't support this kind of EDIFACT segment (yet), so # just create a generic Segment() s = Segment(name, *elements) if validate: if not s.validate(): raise EDISyntaxError( "could not create '{}' Segment. Validation failed.".format( name)) # FIXME: characters is not used! return Segment(name, *elements)
def get_messages(self) -> List[Message]: message = None for segment in self.segments: if segment.tag == "UNH": if not message: message = Message(segment.elements[0], segment.elements[1]) else: raise EDISyntaxError( "Missing UNT segment before new UNH: {}".format( segment)) elif segment.tag == "UNT": if message: yield message else: raise EDISyntaxError( 'UNT segment without matching UNH: "{}"'.format( segment)) else: if message: message.add_segment(segment)
def get_messages(self) -> List[Message]: """parses a list of messages out of the internal segments. :raises EDISyntaxError if constraints are not met (e.g. UNH/UNT both correct) TODO: parts of this here are better done in the validate() method """ message = None last_segment = None for segment in self.segments: if segment.tag == "UNH": if not message: message = Message(segment.elements[0], segment.elements[1]) last_segment = segment else: raise EDISyntaxError( "Missing UNT segment before new UNH: {}".format( segment)) elif segment.tag == "UNT": if message: yield message message = None last_segment = segment else: raise EDISyntaxError( 'UNT segment without matching UNH: "{}"'.format( segment)) else: if message: message.add_segment(segment) last_segment = segment if last_segment: if not last_segment.tag == "UNT": raise EDISyntaxError( "UNH segment was not closed with a UNT segment.")