mt940/models.py
def parse(self, data):
        '''Parses mt940 data, expects a string with data

        Args:
            data (str): The MT940 data

        Returns: :py:class:`list` of :py:class:`Transaction`
        '''
        # Remove extraneous whitespace and such
        data = '\n'.join(self.strip(data.split('\n')))

        # The pattern is a bit annoying to match by regex, even with a greedy
        # match it's difficult to get both the beginning and the end so we're
        # working around it in a safer way to get everything.
        tag_re = re.compile(
            r'^:\n?(?P<full_tag>(?P<tag>[0-9]{2}|NS)(?P<sub_tag>[A-Z])?):',
            re.MULTILINE)
        matches = list(tag_re.finditer(data))

        # identify valid matches
        valid_matches = list(self.sanatize_tag_id_matches(matches))

        for i, match in enumerate(valid_matches):
            tag_id = self.normalize_tag_id(match.group('tag'))

            # get tag instance corresponding to tag id
            tag = self.tags.get(match.group('full_tag')) \
                or self.tags[tag_id]

            # Nice trick to get all the text that is part of this tag, python
            # regex matches have a `end()` and `start()` to indicate the start
            # and end index of the match.

            if valid_matches[i + 1:]:
                tag_data = \
                    data[match.end():valid_matches[i + 1].start()].strip()
            else:
                tag_data = data[match.end():].strip()

            tag_dict = tag.parse(self, tag_data)

            # Preprocess data before creating the object

            for processor in self.processors.get('pre_%s' % tag.slug, []):
                tag_dict = processor(self, tag, tag_dict)

            result = tag(self, tag_dict)

            # Postprocess the object

            for processor in self.processors.get('post_%s' % tag.slug, []):
                result = processor(self, tag, tag_dict, result)

            # Creating a new transaction for :20: and :61: tags allows the
            # tags from :20: to :61: to be captured as part of the transaction.

            if isinstance(tag, mt940.tags.Statement):
                # Transactions only get a Transaction Reference Code ID from a
                # :61: tag which is why a new transaction is created if the
                # 'id' has a value.

                if not self.transactions:
                    transaction = Transaction(self)
                    self.transactions.append(transaction)

                if transaction.data.get('id'):
                    transaction = Transaction(self, result)
                    self.transactions.append(transaction)
                else:
                    transaction.data.update(result)
            elif issubclass(tag.scope, Transaction) and self.transactions:
                # Combine multiple results together as one string, Rabobank has
                # multiple :86: tags for a single transaction

                for k, v in _compat.iteritems(result):
                    if k in transaction.data and hasattr(v, 'strip'):
                        transaction.data[k] += '\n%s' % v.strip()
                    else:
                        transaction.data[k] = v

            elif issubclass(tag.scope, Transactions):  # pragma: no branch
                self.data.update(result)

        return self.transactions
def parse(self, data):
        '''Parses mt940 data, expects a string with data

        Args:
            data (str): The MT940 data

        Returns: :py:class:`list` of :py:class:`Transaction`
        '''
        # Remove extraneous whitespace and such
        data = '\n'.join(self.strip(data.split('\n')))

        # The pattern is a bit annoying to match by regex, even with a greedy
        # match it's difficult to get both the beginning and the end so we're
        # working around it in a safer way to get everything.
        tag_re = re.compile(
            r'^:\n?(?P<full_tag>(?P<tag>[0-9]{2}|NS)(?P<sub_tag>[A-Z])?):',
            re.MULTILINE)
        matches = list(tag_re.finditer(data))

        # identify valid matches
        valid_matches = list(self.sanatize_tag_id_matches(matches))

        for i, match in enumerate(valid_matches):
            tag_id = self.normalize_tag_id(match.group('tag'))

            # get tag instance corresponding to tag id
            tag = self.tags.get(match.group('full_tag')) \
                or self.tags[tag_id]

            # Nice trick to get all the text that is part of this tag, python
            # regex matches have a `end()` and `start()` to indicate the start
            # and end index of the match.

            if valid_matches[i + 1:]:
                tag_data = \
                    data[match.end():valid_matches[i + 1].start()].strip()
            else:
                tag_data = data[match.end():].strip()

            tag_dict = tag.parse(self, tag_data)

            # Preprocess data before creating the object

            for processor in self.processors.get('pre_%s' % tag.slug, []):
                tag_dict = processor(self, tag, tag_dict)

            result = tag(self, tag_dict)

            # Postprocess the object

            for processor in self.processors.get('post_%s' % tag.slug, []):
                result = processor(self, tag, tag_dict, result)

            # Creating a new transaction for :20: and :61: tags allows the
            # tags from :20: to :61: to be captured as part of the transaction.

            if isinstance(tag, mt940.tags.Statement):
                # Transactions only get a Transaction Reference Code ID from a
                # :61: tag which is why a new transaction is created if the
                # 'id' has a value.

                if not self.transactions:
                    transaction = Transaction(self)
                    self.transactions.append(transaction)

                if transaction.data.get('id'):
                    transaction = Transaction(self, result)
                    self.transactions.append(transaction)
                else:
                    transaction.data.update(result)
            elif issubclass(tag.scope, Transaction) and self.transactions:
                # Combine multiple results together as one string, Rabobank has
                # multiple :86: tags for a single transaction

                for k, v in _compat.iteritems(result):
                    if k in transaction.data and hasattr(v, 'strip'):
                        transaction.data[k] += '\n%s' % v.strip()
                    else:
                        transaction.data[k] = v

            elif issubclass(tag.scope, Transactions):  # pragma: no branch
                self.data.update(result)

        return self.transactions
def parse ( self , data ) : # Remove extraneous whitespace and such data = '\n' . join ( self . strip ( data . split ( '\n' ) ) ) # The pattern is a bit annoying to match by regex, even with a greedy # match it's difficult to get both the beginning and the end so we're # working around it in a safer way to get everything. tag_re = re . compile ( r'^:\n?(?P<full_tag>(?P<tag>[0-9]{2}|NS)(?P<sub_tag>[A-Z])?):' , re . MULTILINE ) matches = list ( tag_re . finditer ( data ) ) # identify valid matches valid_matches = list ( self . sanatize_tag_id_matches ( matches ) ) for i , match in enumerate ( valid_matches ) : tag_id = self . normalize_tag_id ( match . group ( 'tag' ) ) # get tag instance corresponding to tag id tag = self . tags . get ( match . group ( 'full_tag' ) ) or self . tags [ tag_id ] # Nice trick to get all the text that is part of this tag, python # regex matches have a `end()` and `start()` to indicate the start # and end index of the match. if valid_matches [ i + 1 : ] : tag_data = data [ match . end ( ) : valid_matches [ i + 1 ] . start ( ) ] . strip ( ) else : tag_data = data [ match . end ( ) : ] . strip ( ) tag_dict = tag . parse ( self , tag_data ) # Preprocess data before creating the object for processor in self . processors . get ( 'pre_%s' % tag . slug , [ ] ) : tag_dict = processor ( self , tag , tag_dict ) result = tag ( self , tag_dict ) # Postprocess the object for processor in self . processors . get ( 'post_%s' % tag . slug , [ ] ) : result = processor ( self , tag , tag_dict , result ) # Creating a new transaction for :20: and :61: tags allows the # tags from :20: to :61: to be captured as part of the transaction. if isinstance ( tag , mt940 . tags . Statement ) : # Transactions only get a Transaction Reference Code ID from a # :61: tag which is why a new transaction is created if the # 'id' has a value. if not self . transactions : transaction = Transaction ( self ) self . transactions . append ( transaction ) if transaction . data . get ( 'id' ) : transaction = Transaction ( self , result ) self . transactions . append ( transaction ) else : transaction . data . update ( result ) elif issubclass ( tag . scope , Transaction ) and self . transactions : # Combine multiple results together as one string, Rabobank has # multiple :86: tags for a single transaction for k , v in _compat . iteritems ( result ) : if k in transaction . data and hasattr ( v , 'strip' ) : transaction . data [ k ] += '\n%s' % v . strip ( ) else : transaction . data [ k ] = v elif issubclass ( tag . scope , Transactions ) : # pragma: no branch self . data . update ( result ) return self . transactions
Parses mt940 data, expects a string with data

        Args:
            data (str): The MT940 data

        Returns: :py:class:`list` of :py:class:`Transaction`
Parses mt940 data expects a string with data