Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/optimizations #89

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions mt940/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import re
import decimal
import datetime
from decimal import Decimal
from datetime import date, datetime, timedelta, tzinfo

# python 3.8+ compatibility
try: # pragma: no cover
Expand All @@ -20,7 +20,7 @@ def __repr__(self):
return '<%s>' % self.__class__.__name__


class FixedOffset(datetime.tzinfo):
class FixedOffset(tzinfo):
'''Fixed time offset based on the Python docs
Source: https://docs.python.org/2/library/datetime.html#tzinfo-objects

Expand All @@ -38,19 +38,19 @@ def __init__(self, offset=0, name=None):

if not isinstance(offset, int):
offset = int(offset)
self._offset = datetime.timedelta(minutes=offset)
self._offset = timedelta(minutes=offset)

def utcoffset(self, dt):
return self._offset

def dst(self, dt):
return datetime.timedelta(0)
return timedelta(0)

def tzname(self, dt):
return self._name


class DateTime(datetime.datetime, Model):
class DateTime(datetime, Model):
'''Just a regular datetime object which supports dates given as strings

>>> DateTime(year='2000', month='1', day='2', hour='3', minute='4',
Expand Down Expand Up @@ -116,12 +116,12 @@ def __new__(cls, *args, **kwargs):
if kwargs.get('offset'):
values['tzinfo'] = FixedOffset(kwargs['offset'])

return datetime.datetime.__new__(cls, **values)
return datetime.__new__(cls, **values)
else:
return datetime.datetime.__new__(cls, *args, **kwargs)
return datetime.__new__(cls, *args, **kwargs)


class Date(datetime.date, Model):
class Date(date, Model):
'''Just a regular date object which supports dates given as strings

>>> Date(year='2000', month='1', day='2')
Expand All @@ -140,9 +140,9 @@ def __new__(cls, *args, **kwargs):
if kwargs:
dt = DateTime(*args, **kwargs).date()

return datetime.date.__new__(cls, dt.year, dt.month, dt.day)
return date.__new__(cls, dt.year, dt.month, dt.day)
else:
return datetime.date.__new__(cls, *args, **kwargs)
return date.__new__(cls, *args, **kwargs)


class Amount(Model):
Expand All @@ -160,7 +160,7 @@ class Amount(Model):
'''

def __init__(self, amount, status, currency=None, **kwargs):
self.amount = decimal.Decimal(amount.replace(',', '.'))
self.amount = Decimal(amount.replace(',', '.'))
self.currency = currency

# C = credit, D = debit
Expand Down Expand Up @@ -230,6 +230,15 @@ def __str__(self):
self.date, )


# 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
)


class Transactions(abc.Sequence):
'''
Collection of :py:class:`Transaction` objects with global properties such
Expand Down Expand Up @@ -393,12 +402,6 @@ 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
Expand Down
35 changes: 18 additions & 17 deletions mt940/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,16 @@ def unique(*args, **kwargs):

Enum = object

from . import models
from .models import (Amount, Balance, Date, DateTime, SumAmount,
Transaction, Transactions)

logger = logging.getLogger(__name__)


class Tag(object):
id = 0
RE_FLAGS = re.IGNORECASE | re.VERBOSE | re.UNICODE
scope = models.Transactions
scope = Transactions

def __init__(self):
self.re = re.compile(self.pattern, self.RE_FLAGS)
Expand Down Expand Up @@ -118,7 +119,7 @@ class DateTimeIndication(Tag):
def __call__(self, transactions, value):
data = super(DateTimeIndication, self).__call__(transactions, value)
return {
'date': models.DateTime(**data)
'date': DateTime(**data)
}


Expand Down Expand Up @@ -182,16 +183,16 @@ def __call__(self, transactions, value):
data = super(FloorLimitIndicator, self).__call__(transactions, value)
if data['status']:
return {
data['status'].lower() + '_floor_limit': models.Amount(**data)
data['status'].lower() + '_floor_limit': Amount(**data)
}

data_d = data.copy()
data_c = data.copy()
data_d.update({'status': 'D'})
data_c.update({'status': 'C'})
return {
'd_floor_limit': models.Amount(**data_d),
'c_floor_limit': models.Amount(**data_c)
'd_floor_limit': Amount(**data_d),
'c_floor_limit': Amount(**data_c)
}


Expand All @@ -207,7 +208,7 @@ class NonSwift(Tag):
Pattern: `2!n35x | *x`
'''

class scope(models.Transaction, models.Transactions):
class scope(Transaction, Transactions):
pass
id = 'NS'

Expand Down Expand Up @@ -262,10 +263,10 @@ class BalanceBase(Tag):

def __call__(self, transactions, value):
data = super(BalanceBase, self).__call__(transactions, value)
data['amount'] = models.Amount(**data)
data['date'] = models.Date(**data)
data['amount'] = Amount(**data)
data['date'] = Date(**data)
return {
self.slug: models.Balance(**data)
self.slug: Balance(**data)
}


Expand All @@ -288,7 +289,7 @@ class Statement(Tag):
Pattern: 6!n[4!n]2a[1!a]15d1!a3!c23x[//16x]
'''
id = 61
scope = models.Transaction
scope = Transaction
pattern = r'''^
(?P<year>\d{2}) # 6!n Value Date (YYMMDD)
(?P<month>\d{2})
Expand All @@ -310,11 +311,11 @@ def __call__(self, transactions, value):
data = super(Statement, self).__call__(transactions, value)
data.setdefault('currency', transactions.currency)

data['amount'] = models.Amount(**data)
date = data['date'] = models.Date(**data)
data['amount'] = Amount(**data)
date = data['date'] = Date(**data)

if data.get('entry_day') and data.get('entry_month'):
entry_date = data['entry_date'] = models.Date(
entry_date = data['entry_date'] = Date(
day=data.get('entry_day'),
month=data.get('entry_month'),
year=str(data['date'].year),
Expand All @@ -327,7 +328,7 @@ def __call__(self, transactions, value):
else:
year = 0

data['guessed_entry_date'] = models.Date(
data['guessed_entry_date'] = Date(
day=entry_date.day,
month=entry_date.month,
year=entry_date.year + year,
Expand Down Expand Up @@ -400,7 +401,7 @@ class TransactionDetails(Tag):
Pattern: 6x65x
'''
id = 86
scope = models.Transaction
scope = Transaction
pattern = r'''
(?P<transaction_details>(([\s\S]{0,65}\r?\n?){0,8}[\s\S]{0,65}))
'''
Expand All @@ -423,7 +424,7 @@ def __call__(self, transactions, value):

data['status'] = self.status
return {
self.slug: models.SumAmount(**data)
self.slug: SumAmount(**data)
}


Expand Down