Repository: markusressel/barcode-server (language: python)

Issue:
'InputEvent' object has no attribute 'event'
I tried setting up the server with docker but everytime a scan a code i get an error. I tried different /dev/input devices but i get the same error everytime.

```
barcode    | 2022-01-24 17:03:37,539 - barcode_server - INFO - === barcode-server ===
barcode    | 2022-01-24 17:03:37,539 - barcode_server - INFO - Instance ID: vorratsschrank-1
barcode    | 2022-01-24 17:03:37,550 - barcode_server - INFO - Starting statistics webserver...
barcode    | 2022-01-24 17:03:37,552 - barcode_server.webserver - DEBUG - Starting notifier: mqtt
barcode    | 2022-01-24 17:03:37,553 - barcode_server.webserver - INFO - Starting webserver on 127.0.0.1:9654 ...
barcode    | 2022-01-24 17:03:37,554 - barcode_server.barcode - INFO - Reading: /dev/input/event15: Name: ARM CM0 USB HID Keyboard, Vendor: ffff, Product: 0035
barcode    | 2022-01-24 17:05:33,172 - barcode_server.barcode - ERROR - 'InputEvent' object has no attribute 'event'
barcode    | Traceback (most recent call last):
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/barcode.py", line 94, in _start_reader
barcode    |     barcode = await self._read_line(input_device)
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/barcode.py", line 152, in _read_line
barcode    |     result = await loop.run_in_executor(None, self._keyevent_reader.read_line, input_device)
barcode    |   File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
barcode    |     result = self.fn(*self.args, **self.kwargs)
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/keyevent_reader.py", line 57, in read_line
barcode    |     if isinstance(event, KeyEvent) or event.event.type == 1:
barcode    | AttributeError: 'InputEvent' object has no attribute 'event'
barcode    | 2022-01-24 17:05:33,827 - barcode_server.barcode - INFO - Reading: /dev/input/event15: Name: ARM CM0 USB HID Keyboard, Vendor: ffff, Product: 0035
barcode    | 2022-01-24 17:05:42,220 - barcode_server.barcode - ERROR - 'InputEvent' object has no attribute 'event'
barcode    | Traceback (most recent call last):
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/barcode.py", line 94, in _start_reader
barcode    |     barcode = await self._read_line(input_device)
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/barcode.py", line 152, in _read_line
barcode    |     result = await loop.run_in_executor(None, self._keyevent_reader.read_line, input_device)
barcode    |   File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
barcode    |     result = self.fn(*self.args, **self.kwargs)
barcode    |   File "/usr/local/lib/python3.9/site-packages/barcode_server/keyevent_reader.py", line 57, in read_line
barcode    |     if isinstance(event, KeyEvent) or event.event.type == 1:
barcode    | AttributeError: 'InputEvent' object has no attribute 'event'
barcode    | 2022-01-24 17:05:42,848 - barcode_server.barcode - INFO - Reading: /dev/input/event15: Name: ARM CM0 USB HID Keyboard, Vendor: ffff, Product: 0035
```

My docker compose file:

```
version: '2.2'
services:
  barcode:
    image: markusressel/barcode-server:v2.2.0
    restart: always
    container_name: barcode
    volumes:
      - ./config/barcode_server.yml:/app/barcode_server.yaml
    devices:
     - "/dev/input/by-id/usb-ARM_CM0_USB_HID_Keyboard_8A2D1FD80F03-event-kbd:/dev/input/by-id/usb-ARM_CM0_USB_HID_Keyboard_8A2D1FD80F03-event-kbd"
     - "/dev/input/event15:/dev/input/event15"
    environment:
     - PUID=0
     - PGID=0
    ports:
      - "9655:8000"
      - "9654:9654"
```

And my config device_path looks like this:

```
   ...
  device_paths:
    - "/dev/input/event15"
   ....
```


Discussion / hints:
Thx for the report.

Not sure what the exact cause of this is, I will try to investigate. Did you try earlier versions? Do they show similar behaviour?
I tried using the native method instead on a raspberry pi instead(docker was on amd cpu). But the setup always ends with errors. 
Will check some older docker versions later.
v2.0.0 works on the same system. Didn't test any other versions.

Fix patch:
diff --git a/barcode_server/keyevent_reader.py b/barcode_server/keyevent_reader.py
index 75615a0..5ff630b 100644
--- a/barcode_server/keyevent_reader.py
+++ b/barcode_server/keyevent_reader.py
@@ -54,9 +54,15 @@ def read_line(self, input_device: InputDevice) -> str:
         # async for event in input_device.async_read_loop():
         for event in input_device.read_loop():
             event = categorize(event)
-            if isinstance(event, KeyEvent) or event.event.type == 1:
+
+            if hasattr(event, "event"):
                 if not hasattr(event, "keystate"):
                     event.keystate = event.event.keystate
+
+            if isinstance(event, KeyEvent):
+                if self._on_key_event(event):
+                    return self._line
+            elif hasattr(event, "event") and event.event.type == 1:
                 if self._on_key_event(event):
                     return self._line
 


Test patch:
diff --git a/tests/key_event_reader_test.py b/tests/key_event_reader_test.py
index a9db7b3..b5f5311 100644
--- a/tests/key_event_reader_test.py
+++ b/tests/key_event_reader_test.py
@@ -125,3 +125,20 @@ async def test_special_characters(self):
 
         # THEN
         self.assertEqual(expected, line)
+
+    async def test_event_without_event_attribute(self):
+        # GIVEN
+        under_test = KeyEventReader()
+        expected = "0"
+        input_events = self.generate_input_event_sequence(expected)
+        for event in input_events:
+            delattr(event, "event")
+
+        input_device = Mock()
+        input_device.read_loop = self.fake_input_loop(input_events)
+
+        # WHEN
+        line = under_test.read_line(input_device)
+
+        # THEN
+        self.assertEqual(expected, line)