Skip to content

Commit

Permalink
Merge pull request #13 from wirelane/feature/SWPROD-4926
Browse files Browse the repository at this point in the history
SWPROD-4926: remove unused packages and update remaining
  • Loading branch information
andythedandy authored Aug 23, 2023
2 parents d78548f + 179b66b commit 1290d8d
Show file tree
Hide file tree
Showing 23 changed files with 127 additions and 302 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 120
31 changes: 31 additions & 0 deletions .github/workflows/pull_requests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Run lint and tests

on:
pull_request:
branches:
- py3

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- run: |
python -m pip install --upgrade pip
pip install -r ecrterm/requirements.txt
- run: flake8 ecrterm/

test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.9'
- run: |
python -m pip install --upgrade pip
pip install -r ecrterm/requirements.txt
- run: python -m unittest discover -s ecrterm/tests/
5 changes: 0 additions & 5 deletions .isort.cfg

This file was deleted.

66 changes: 0 additions & 66 deletions .screenrc

This file was deleted.

10 changes: 0 additions & 10 deletions .travis.yml

This file was deleted.

7 changes: 0 additions & 7 deletions MANIFEST.in

This file was deleted.

2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
[![Build Status](https://travis-ci.org/karolyi/py3-ecrterm.svg?branch=master)](https://travis-ci.org/karolyi/py3-ecrterm)

ecrterm
=======

Expand Down
2 changes: 1 addition & 1 deletion ecrterm/ecr.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def listen(self, timeout=15):
ok, message = self.transport.receive(timeout)
if ok and message:
return message
except:
except Exception:
logger.exception()
continue
print('-mark-')
Expand Down
32 changes: 15 additions & 17 deletions ecrterm/packets/apdu.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""Classes and Functions which deal with the APDU Layer."""

from typing import TypeVar, Type
from typing import TypeVar, Type, List, Union, Tuple, Any
from collections import OrderedDict

from .fields import *
from .bitmaps import BITMAPS
from .fields import Field, ParseError

# Currencies
CC_EUR = '0978'
Expand Down Expand Up @@ -70,8 +70,8 @@ def as_dict(self):

def items(self):
return \
[(name, getattr(self, name)) for (name, field) in self.FIELDS.items() if field in self._values] + \
[(name, getattr(self, name)) for name in self._bitmaps.keys()]
[(name, getattr(self, name)) for (name, field) in self.FIELDS.items() if field in self._values] + \
[(name, getattr(self, name)) for name in self._bitmaps.keys()]

def __repr__(self):
reps = [
Expand Down Expand Up @@ -141,11 +141,11 @@ def __setattr__(self, item, value):
super().__setattr__(item, value)

@staticmethod
def compute_length_field(l: int) -> bytes:
if l < 255:
return bytes([l])
if l < 256 * 256 - 1:
return bytes([0xff, l & 0xff, (l >> 8) & 0xff])
def compute_length_field(length: int) -> bytes:
if length < 255:
return bytes([length])
if length < 256 * 256 - 1:
return bytes([0xff, length & 0xff, (length >> 8) & 0xff])
raise ValueError

@classmethod
Expand Down Expand Up @@ -205,7 +205,7 @@ def parse(cls: Type[APDUType], data: Union[bytes, List[int]]) -> APDUType:
except ParseError as e:
blacklist_candidates = [
f for f in retval.FIELDS.values()
if not f.required and f.ignore_parse_error and not f in blacklist
if not f.required and f.ignore_parse_error and f not in blacklist
]
if not blacklist_candidates:
# No more we can do, probably really a parse error
Expand All @@ -217,9 +217,7 @@ def parse(cls: Type[APDUType], data: Union[bytes, List[int]]) -> APDUType:
# FIXME Mandatory fields.
return retval



def _parse_inner(self, data:bytes, blacklist: List[Field]) -> Union[List[Tuple[str, Any]], Field]:
def _parse_inner(self, data: bytes, blacklist: List[Field]) -> Union[List[Tuple[str, Any]], Field]:
# ~~~~ Strategy to parse the SUPER CURSED Completion packet ~~~~
# A) When a Field parser marked required=False, ignore_parse_error=True fails
# it gets added to the blacklist and not tried again
Expand Down Expand Up @@ -288,9 +286,9 @@ def __init__(self, *args, **kwargs):
def can_parse(cls, data: Union[bytes, List[int]]) -> bool:
data = bytes(data)
return len(data) >= 2 and (
cls.CMD_CLASS is Ellipsis or cls.CMD_CLASS == data[0]
cls.CMD_CLASS is Ellipsis or cls.CMD_CLASS == data[0]
) and (
cls.CMD_INSTR is Ellipsis or cls.CMD_INSTR == data[1]
cls.CMD_INSTR is Ellipsis or cls.CMD_INSTR == data[1]
)

@property
Expand Down Expand Up @@ -321,9 +319,9 @@ def __init__(self, *args, **kwargs):
def can_parse(cls, data: Union[bytes, List[int]]) -> bool:
data = bytes(data)
return len(data) >= 2 and (
cls.RESP_CCRC is Ellipsis or cls.RESP_CCRC == data[0]
cls.RESP_CCRC is Ellipsis or cls.RESP_CCRC == data[0]
) and (
cls.RESP_APRC is Ellipsis or cls.RESP_APRC == data[1]
cls.RESP_APRC is Ellipsis or cls.RESP_APRC == data[1]
)

@property
Expand Down
85 changes: 4 additions & 81 deletions ecrterm/packets/base_packets.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import datetime
import struct
from typing import Dict
from typing import Dict, List, Optional, Union

from .apdu import CommandAPDU
from .fields import *
from .fields import BCDField, FlagByteField, BCDIntField, LLLStringField, ByteField, StringField
from .text_encoding import ZVT_7BIT_CHARACTER_SET
from .types import *
from .types import ConfigByte, CurrencyCode


class Packet(CommandAPDU):
Expand Down Expand Up @@ -260,92 +259,16 @@ def get_end_of_day_information(self):
- receipt-number-start, receipt-number-end contain the range of
receipts
"""
ret = {}
# create a dictionary of bitmaps:
bdict = self.as_dict()
# at least amount should be present:
if 'amount' not in bdict.keys():
return {}
else:
ret = {'amount': bdict['amount'], }
return {'amount': bdict['amount'], }
# bitmap 0x60 (totals) contains the required information.
# another bitmap (amount) holds the amount

## FIXME Parsing of totals in the parser
return ret

if 'totals' not in bdict.keys():
# this packet holds no detail information but an amount.
return ret
totals = bdict['totals']
totals_list = totals.value()
# totals_list = str(bdict['totals'])
# now we build our real data our of it.

# rebuild date and time.
my_time = None
my_date = None
if 'time' in bdict.keys():
# print bdict['time'].value()
mt = str(bdict['time'].value())
my_time = datetime.time(
hour=int(mt[0:2]), minute=int(mt[2:4]), second=int(mt[4:6]))
if 'date_day' in bdict.keys():
# print bdict['date'].value()
md = str(bdict['date_day'].value())
my_date = datetime.date(
year=datetime.datetime.now().year, month=int(md[0:2]),
day=int(md[2:4]))
ret = {
'receipt-number-start':
BCD.as_int(BCD.decode_bcd(totals_list[0:2])),
'receipt-number-end':
BCD.as_int(BCD.decode_bcd(totals_list[2:4])),
'number-ec-card': bs2hl(totals_list[4])[0],
'turnover-ec-card':
BCD.as_int(BCD.decode_bcd(totals_list[5:5 + 6])),
'number-jcb': bs2hl(totals_list[11])[0],
'turnover-jcb': BCD.as_int(BCD.decode_bcd(totals_list[12:12 + 6])),
'number-eurocard': bs2hl(totals_list[18])[0],
'turnover-eurocard':
BCD.as_int(BCD.decode_bcd(totals_list[19:19 + 6])),
'number-amex': bs2hl(totals_list[25])[0],
'turnover-amex':
BCD.as_int(BCD.decode_bcd(totals_list[26:26 + 6])),
'number-visa': bs2hl(totals_list[32])[0],
'turnover-visa':
BCD.as_int(BCD.decode_bcd(totals_list[33:33 + 6])),
'number-diners': bs2hl(totals_list[39])[0],
'turnover-diners':
BCD.as_int(BCD.decode_bcd(totals_list[40:40 + 6])),
'number-remaining': bs2hl(totals_list[46])[0],
'turnover-remaining':
BCD.as_int(BCD.decode_bcd(totals_list[47:47 + 6])),
'amount': int(bdict['amount'].value()),
'turnover-amount': int(bdict['amount'].value()),
'date': my_date,
'time': my_time,
'number-total': 0,
}
# time holds simply HHMMSS (BCD)
# date holds simply mmdd (BCD)

# adding a formatted version
tn = 0
float_version = {}
for key, value in ret.items():
if key.startswith('turnover-'):
key_id = key.replace('turnover-', '')
# add a key with a formatted representation.
v = float(value) / 100.0
float_version['float-%s' % key_id] = v
elif key.startswith('number-'):
# add total numbers.
tn += int(value)
ret['number-total'] = tn
ret.update(float_version)
return ret


class IntermediateStatusInformation(Packet):
"""
Expand Down
5 changes: 3 additions & 2 deletions ecrterm/packets/bitmaps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from .fields import *
from .types import *
from ecrterm.packets.fields import ByteField, FlagByteField, BCDIntField, TLVField, BCDField, LLVARField, LLLVARField, \
FixedLengthField, PasswordField, LLStringField
from ecrterm.packets.types import ServiceByte, CurrencyCode

BITMAPS = {
0x01: (ByteField(), 'timeout', 'binary time-out'),
Expand Down
16 changes: 8 additions & 8 deletions ecrterm/packets/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,25 @@ class LVARField(Field):

def parse(self, data: Union[bytes, List[int]]) -> Tuple[Any, bytes]:
data = bytes(data) if not isinstance(data, bytes) else data
l = 0
length = 0
for i in range(self.LL):
if (data[i] & 0xF0) != 0xF0 or (data[i] & 0x0F) > 9:
raise ParseError("L*VAR length header invalid")
l = (l * 10) + (data[i] & 0x0F)
length = (length * 10) + (data[i] & 0x0F)
data = data[self.LL:]

v, data = data[:l], data[l:]
v, data = data[:length], data[length:]

return self.from_bytes(v), data

def serialize(self, data: Any) -> bytes:
data = self.to_bytes(data)

l = len(data)
if l >= (10 ** self.LL):
length = len(data)
if length >= (10 ** self.LL):
raise ValueError("Data too long for L*VAR field")

header = bytes(0xF0 | ((l // (10 ** i)) % 10) for i in reversed(range(self.LL)))
header = bytes(0xF0 | ((length // (10 ** i)) % 10) for i in reversed(range(self.LL)))
return header + data


Expand Down Expand Up @@ -198,7 +198,7 @@ class FlagByteField(IntField, FixedLengthField):
LENGTH = 1

def __init__(self, *args, **kwargs):
if not 'data_type' in kwargs:
if 'data_type' not in kwargs:
raise TypeError("Must specify data_type")
super().__init__(*args, **kwargs)

Expand Down Expand Up @@ -305,7 +305,7 @@ def serialize(self, data: TLV) -> bytes:
return data.serialize()

def __get__(self, instance, objtype=None) -> TLV:
if not self in instance._values:
if self not in instance._values:
instance._values[self] = TLV()
instance._values[self].pending = True
return super().__get__(instance, objtype)
Expand Down
Loading

0 comments on commit 1290d8d

Please sign in to comment.