diff --git a/.gitignore b/.gitignore index cfbb1c8..fcadbe0 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,10 @@ build-common/bleak_winrt pf2 pf2.zip *.pf2 +# archlinux package build files +cat-printer-git +pkg +*.pkg.tar.zst # dev config config.json # dev backup diff --git a/PKGBUILD b/PKGBUILD index e60e8f1..af5f8e7 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,13 +1,14 @@ # Maintainer : pkgname=cat-printer-git -pkgver=r30.eafaa6e +pkgver=r153.85cb5a8 pkgrel=1 pkgdesc="A project that provides support to some Bluetooth Cat Printer models, on many platforms!" arch=('any') url="https://github.com/NaitLee/Cat-Printer" license=('GPL3') -depends=('python' 'bluez' 'bluez-utils' 'python-bleak' 'ghostscript' 'imagemagick') +depends=('python' 'bluez' 'python-bleak') +optdepends=('bluez-utils' 'ghostscript' 'imagemagick') makedepends=('git' 'unzip') provides=("cat-printer=${pkgver}") source=("$pkgname::git+https://github.com/NaitLee/Cat-Printer.git") diff --git a/printer.py b/printer.py index 5d35a52..c2839d7 100644 --- a/printer.py +++ b/printer.py @@ -23,6 +23,7 @@ class ExitCodes(): PrinterError = 64 IncompleteProgram = 128 MissingDependency = 129 + UserInterrupt = 254 def info(*args, **kwargs): 'Just `print` to `stdout`' @@ -345,7 +346,7 @@ def connect(self, name=None, address=None): self.device = None if name is None and address is None: return - self.model = Models[name] + self.model = Models.get(name, Models['_ZZ00']) self.device = BleakClient(address) def notify(_char, data): if data == self.data_flow_pause: @@ -595,10 +596,10 @@ def fallback_program(*programs): def magick_text(stdin, image_width, font_size, font_family): 'Pipe an io to ImageMagick for processing text to image, return output io' - read_fd, write_fd = os.pipe() if _MagickExe is None: - fatal(i18n("imagemagick-not-found"), code=129) - + fatal(i18n("imagemagick-not-found"), code=ExitCodes.MissingDependency) + + read_fd, write_fd = os.pipe() subprocess.Popen([_MagickExe, '-background', 'white', '-fill', 'black', '-size', f'{image_width}x', '-font', font_family, '-pointsize', str(font_size), 'caption:@-', 'pbm:-'], @@ -607,10 +608,10 @@ def magick_text(stdin, image_width, font_size, font_family): def magick_image(stdin, image_width, dither): 'Pipe an io to ImageMagick for processing "usual" image to pbm, return output io' - read_fd, write_fd = os.pipe() if _MagickExe is None: - fatal(i18n("imagemagick-not-found"), code=129) + fatal(i18n("imagemagick-not-found"), code=ExitCodes.MissingDependency) + read_fd, write_fd = os.pipe() subprocess.Popen([_MagickExe, '-', '-fill', 'white', '-opaque', 'transparent', '-resize', f'{image_width}x', '-dither', dither, '-monochrome', 'pbm:-'], stdin=stdin, stdout=io.FileIO(write_fd, 'w')) @@ -677,6 +678,10 @@ def _main(): help=i18n('print-quality')) parser.add_argument('-d', '--dry', action='store_true', help=i18n('dry-run-test-print-process-only')) + parser.add_argument('-u', '--unknown', action='store_true', + help=i18n('try-to-print-through-an-unknown-device')) + parser.add_argument('-0', '--0th', action='store_true', + help=i18n('no-prompt-for-multiple-devices')) parser.add_argument('-f', '--fake', metavar='XY01', type=str, default='', help=i18n('virtual-run-on-specified-model')) parser.add_argument('-m', '--dump', action='store_true', @@ -729,18 +734,6 @@ def _main(): mode = 'pbm' - # Connect to printer - if args.dry: - info(i18n('dry-run-test-print-process-only')) - printer.dry_run = True - if args.fake: - printer.fake = True - printer.model = Models[args.fake] - else: - info(i18n('connecting')) - printer.scan(identifier, use_result=True) - printer.dump = args.dump - # Prepare image / text if args.text: info(i18n('text-printing-mode')) @@ -758,15 +751,46 @@ def _main(): else 'FloydSteinberg') ) + # Connect to printer + if args.dry: + info(i18n('dry-run-test-print-process-only')) + printer.dry_run = True + if args.fake: + printer.fake = True + printer.model = Models[args.fake] + else: + info(i18n('scanning-for-devices')) + devices = printer.scan(identifier, everything=args.unknown) + + printer.dump = args.dump + if args.nothing: global Printer Printer = printer return + if len(devices) == 0: + error(i18n('no-available-devices-found'), error=PrinterError) + if len(devices) == 1 or getattr(args, '0th'): + info(i18n('connecting')) + printer.connect(devices[0].name, devices[0].address) + else: + info(i18n('there-are-multiple-devices-')) + for i in range(len(devices)): + d = devices[i] + n = str(d.name) + "-" + d.address[3:5] + d.address[0:2] + info('%4i\t%s' % (i, n)) + choice = 0 + try: + choice = int(input(i18n('choose-which-one-0-', choice))) + except KeyboardInterrupt: + raise + except: + pass + info(i18n('connecting')) + printer.connect(devices[choice].name, devices[choice].address) try: printer.print(file, mode=mode) info(i18n('finished')) - except KeyboardInterrupt: - info(i18n('stopping')) finally: file.close() printer.unload() @@ -778,8 +802,9 @@ def main(): except BleakError as e: error_message = str(e) if ( - ('not turned on' in error_message) or # windows or android - (isinstance(e, BleakDBusError) and # linux/dbus/bluetoothctl + 'not turned on' in error_message or + 'No powered Bluetooth adapter' in error_message or + (isinstance(e, BleakDBusError) and getattr(e, 'dbus_error') == 'org.bluez.Error.NotReady') ): fatal(i18n('please-enable-bluetooth'), code=ExitCodes.GeneralError) @@ -789,9 +814,11 @@ def main(): fatal(e.message_localized, code=ExitCodes.PrinterError) except RuntimeError as e: if 'no running event loop' in str(e): - pass # non-sense + pass # ignore this else: raise + except KeyboardInterrupt: + fatal(i18n('stopping'), code=ExitCodes.UserInterrupt) if __name__ == '__main__': main() diff --git a/printer_lib/models.py b/printer_lib/models.py index a181a7f..989ad62 100644 --- a/printer_lib/models.py +++ b/printer_lib/models.py @@ -19,7 +19,7 @@ class Model(): Models = {} # all known supported models -for name in 'GB01 GB02 GB03 GT01 MX05 MX06 YT01'.split(' '): +for name in '_ZZ00 GB01 GB02 GB03 GT01 MX05 MX06 MX08 YT01'.split(' '): Models[name] = Model() # that can receive compressed data @@ -27,5 +27,5 @@ class Model(): Models[name].is_new_kind = True # that have problem giving feed command -for name in 'MX05 MX06'.split(' '): +for name in 'MX05 MX06 MX08'.split(' '): Models[name].problem_feeding = True diff --git a/server.py b/server.py index d7ea124..fa2d06c 100644 --- a/server.py +++ b/server.py @@ -74,13 +74,13 @@ class PrinterServerHandler(BaseHTTPRequestHandler): settings = DictAsObject({ 'config_path': 'config.json', - 'version': 3, + 'version': 4, 'first_run': True, 'is_android': False, 'scan_time': 4.0, 'dry_run': False, 'energy': 64, - 'quality': 32 + 'quality': 36 }) _settings_blacklist = ( 'printer', 'is_android' diff --git a/www/about.html b/www/about.html index 81b6f87..b5e8e70 100644 --- a/www/about.html +++ b/www/about.html @@ -45,6 +45,12 @@

Contributors

Collaborator
Translator
+
+
+ nodlek-ctrl +
+
Minor Tweaks
+
All testers & users
Everyone is awesome!
@@ -52,7 +58,7 @@

Contributors

Copyright

- Copyright © 2021-2022 NaitLee Soft. + Copyright © 2021-2023 NaitLee Soft. Some rights reserved.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

diff --git a/www/index.html b/www/index.html index e80736f..86cfcf5 100644 --- a/www/index.html +++ b/www/index.html @@ -43,17 +43,17 @@

Cat Printer