diff --git a/.forgejo/workflows/package.yml b/.forgejo/workflows/package.yml new file mode 100644 index 0000000..97ce09e --- /dev/null +++ b/.forgejo/workflows/package.yml @@ -0,0 +1,35 @@ +--- + +on: push + +jobs: + + build_debian: + runs-on: docker + container: + image: git.kabelsalat.ch/s3lph/package-pipeline-builder:latest + steps: + - uses: https://code.forgejo.org/actions/checkout@v4 + - name: Prepare package + run: | + mkdir -p \ + package/debian/barcode-utils/usr/bin + package/debian/barcode-utils/usr/share/webextensions + sed -re "s/__VERSION__/0.$(git rev-list --count HEAD)-1/g" -i package/debian/barcode-utils/DEBIAN/control + # barcode-websocket-server + cp barcode-websocket-server package/debian/barcode-utils/usr/bin/ + # webextension-tabfocus + cd webextension-tabfocus + zip "../tabfocus-$(jq .version < manifest.json).zip" * + cd .. + cp tabfocus*zip package/debian/barcode-utils/usr/share/webextensions/ + # package + find package/debian/barcode-utils -exec touch -m -d "$(git log -1 --format="%aI")" {} \; + cd package/debian/ + dpkg-deb --build barcode-utils . + + - uses: https://git.kabelsalat.ch/s3lph/forgejo-action-debian-package-upload@v2 + with: + username: ${{ secrets.API_USERNAME }} + password: ${{ secrets.API_PASSWORD }} + deb: "package/debian/*.deb" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b0cbbf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tabfocus-0.1.zip diff --git a/barcode-websocket-server b/barcode-websocket-server index 96ccd57..3490ca5 100755 --- a/barcode-websocket-server +++ b/barcode-websocket-server @@ -15,6 +15,12 @@ from websockets.sync.server import serve import hid +HID_USAGE_PAGE_BARCODE_SCANNER = 0x8C +HID_USAGE_BARCODE_SCANNER = 0x02 +HID_REPORT_SCANNED_DATA = 0x12 +HID_REPORT_SCANNED_DATA_MAXLENGTH = 0xFF + + # struct input_event data to move the mouse # the timeval header uses native types, the event data uses platform-independent types # struct timeval { tv_sec = 0, tv_usec = 0 } @@ -29,8 +35,8 @@ evsyn = evhdr + struct.pack('=HHi', 0, 0, 0) class BarcodeServer: def __init__(self, ns): - self.vid = int(ns.vid, 16) - self.pid = int(ns.pid, 16) + self.vid = int(ns.vid, 16) if ns.vid else None + self.pid = int(ns.pid, 16) if ns.pid else None self.url = ns.url self.aim = ns.aim self.chars = ns.chars @@ -93,13 +99,22 @@ class BarcodeServer: while not self.shutdown.is_set(): try: h = hid.device() - h.open(self.vid, self.pid) + if self.vid and self.pid: + h.open(self.vid, self.pid) + else: + # Auto-detect barcode scanners + devs = [x for x in hid.enumerate() + if x['usage_page'] == HID_USAGE_PAGE_BARCODE_SCANNER + and x['usage'] == HID_USAGE_BARCODE_SCANNER] + if not devs: + raise RuntimeError('No USB HID POS barcode scanner found') + h.open(devs[0]['vendor_id'], devs[0]['product_id']) print(f'Device manufacturer: {h.get_manufacturer_string()}') print(f'Product: {h.get_product_string()}') print(f'Serial Number: {h.get_serial_number_string()}') while not self.shutdown.is_set(): - # Line from Honeywell scanner consists of: - # - 0x02 (magic?) + # Line from Honeywell HID POS scanner consists of: + # - 0x02 = HID Report ID "Scanned Data Report" # - 1 byte payload length (without AIM, so 13 for EAN-13) # - 3 bytes AIM, e.g. "]E0" for EAN-13 # - payload bytes @@ -151,9 +166,9 @@ class BarcodeServer: def main(): ap = argparse.ArgumentParser(sys.argv[0], description='Opens a website when a barcode is scanned with an USB-HID barcode scanner.') ap.add_argument('--url', '-u', type=str, help='The URL to open. "{}" is replaced by the barcode data. Default: http://localhost/?ean={}', default='http://localhost/?ean={}') - ap.add_argument('--vid', '-v', type=str, help='The USB vendor ID. Default: 0c2e', default='0c2e') - ap.add_argument('--pid', '-p', type=str, help='The USB product ID. Default: 0b07', default='0b07') - ap.add_argument('--aim', '-A', type=str, help='AIM filter prefix, e.g. "]E0" for EAN13, "]E" for all EAN variants, or "]" for all barcodes. Default: "]E"', default=']E') + ap.add_argument('--vid', '-v', type=str, help='Connect to device using this USB vendor ID.') + ap.add_argument('--pid', '-p', type=str, help='Connect to device using this USB product ID.') + ap.add_argument('--aim', '-A', type=str, help='AIM filter prefix, e.g. "]E0" for EAN13, "]E" for all EAN variants, or "]" for all barcodes. Default: "]"', default=']') ap.add_argument('--chars', '-C', type=str, help='Permitted characters. Defaults to "0123456789"', default='0123456789') ap.add_argument('--ydotool-socket', '-Y', type=str, help='If provided, the ydotool socket to wake the screen.') ap.add_argument('--websocket-host', '-w', type=str, help='Websocket host to listen on. Defaults to "localhost"', default='localhost') diff --git a/package/debian/barcode-utils/DEBIAN/control b/package/debian/barcode-utils/DEBIAN/control new file mode 100644 index 0000000..3916540 --- /dev/null +++ b/package/debian/barcode-utils/DEBIAN/control @@ -0,0 +1,10 @@ +Package: barcode-utils +Version: __VERSION__ +Maintainer: s3lph +Section: utils +Priority: optional +Architecture: all +Depends: python3 (>= 3.6), python3-hid +Description: Miscellaneous utils for dealing with barcodes. + Miscellaneous utils for dealing with barcodes. +