def get_printers_usb(): ''' Get list of printers via `PyUSB.core.find`. Returns ------- List of printers details. Example:: [{'vendor': int, 'product': int, 'in_ep': int, 'out_ep': int}, ...] ''' printers = [] try: for printer in usb.core.find(find_all=True, custom_match=find_class(7)): details = {} details['vendor'] = convert_to_int_or_hex(printer.idVendor) details['product'] = convert_to_int_or_hex(printer.idProduct) try: configuration = printer.get_active_configuration() in_ep = configuration[(0, 0)][0].bEndpointAddress out_ep = configuration[(0, 0)][1].bEndpointAddress details['in_ep'] = convert_to_int_or_hex(in_ep) details['out_ep'] = convert_to_int_or_hex(out_ep) except Exception: pass printers.append(details) except Exception as exception: log_error(exception) return printers
def get_tts_safely(): ''' Helper to read gTTS data from `static/tts.json` file safely. Parameters ---------- failsafe: boolean to silence any encountered errors. Returns ------- Dict of gTTS content. Example:: {"en-us": {"langauge": "English", "message": "new ticket!"}, ...} ''' tts_path = os.path.join(absolute_path('static'), 'tts.json') tts_content = {} try: with open(tts_path, encoding='utf-8') as tts_file: tts_content.update(json.load(tts_file)) except Exception as e: log_error(e) tts_content.update({ 'en-us': { 'language': 'English', 'message': ' , please proceed to the {} number : ' } }) return tts_content
def loop_languages(language): try: gTTs.say( language, self.format_announcement_text( ticket, aliases, language, display_settings.prefix)) successes.append(language) except Exception as exception: log_error(exception, quiet=self.quiet)
def interface(cli, quiet, ip, port): ''' FQM command-line interface (CLI): * if `--cli` is not used, initializing GUI will be attempted.\n * If no `ip` is passed it will default to `127.0.0.1`.\n * If no `port` is passed it will default to a random port.\n ''' app = bundle_app() def start_cli(): alt_ip = '192.168.178.84' or get_accessible_ips()[0][1] alt_port = port or get_random_available_port(alt_ip) app.config['LOCALADDR'] = alt_ip app.config['CLI_OR_DEPLOY'] = True app.config['QUIET'] = quiet click.echo( click.style( f'FQM {VERSION} is running on http://{alt_ip}:{alt_port}', bold=True, fg='green')) click.echo('') click.echo( click.style('Press Control-c to stop', blink=True, fg='black', bg='white')) try: monkey.patch_socket() pywsgi.WSGIServer( (str(alt_ip), int(alt_port)), app, log=None if quiet else 'default').serve_forever() except KeyboardInterrupt: stop_tasks() if cli: start_cli() else: try: app.config['CLI_OR_DEPLOY'] = False gui_process = import_module('PyQt5.QtWidgets').QApplication( sys.argv) window = import_module('app.gui').MainWindow( app) # NOTE: has to be decleared in a var to work properly import_module('PyQt5.QtCore').QCoreApplication.processEvents() gui_process.exec_() except Exception as e: if not quiet: print('Failed to start PyQt GUI, fallback to CLI.') log_error(e, quiet=quiet) start_cli()
def serial(task, office_id=None): ''' generate a new ticket and print it. ''' windows = os.name == 'nt' form = TouchSubmitForm() task = data.Task.get(task.id) office = data.Office.get(office_id) touch_screen_stings = data.Touch_store.get() ticket_settings = data.Printer.get() printed = not touch_screen_stings.n numeric_ticket_form = ticket_settings.value == 2 name_or_number = remove_string_noise(form.name.data or '', lambda s: s.startswith('0'), lambda s: s[1:]) or None # NOTE: if it is registered ticket, will display the form if not form.validate_on_submit() and not printed: return render_template('touch.html', title=touch_screen_stings.title, tnumber=numeric_ticket_form, ts=touch_screen_stings, bgcolor=touch_screen_stings.bgcolor, a=4, done=False, page_title='Touch Screen - Enter name ', form=form, dire='multimedia/', alias=data.Aliases.query.first(), office_id=office_id) new_ticket, exception = data.Serial.create_new_ticket( task, office, name_or_number) if exception: flash('Error: you must have available printer, to use printed', 'danger') flash('Notice: make sure that printer is properly connected', 'info') if windows: flash( 'Notice: Make sure to make the printer shared on the local network', 'info') elif 'linux' in platform: flash( 'Notice: Make sure to execute the command `sudo gpasswd -a $(users) lp` and ' 'reboot the system', 'info') log_error(exception) return redirect(url_for('core.root')) return redirect(url_for('core.touch', a=1, office_id=office_id))
def printer_failure_redirect(exception): flash('Error: you must have available printer, to use printed', 'danger') flash('Notice: make sure that printer is properly connected', 'info') if os.name == 'nt': flash( 'Notice: Make sure to make the printer shared on the local network', 'info') elif 'linux' in platform: flash( 'Notice: Make sure to execute the command `sudo gpasswd -a $(users) lp` and ' 'reboot the system', 'info') log_error(exception) return redirect(url_for('core.root'))
def run(self): while not self.cut_circut: with self.app.app_context(): display_settings = Display_store.query.first() if display_settings.announce != 'false': aliases = Aliases.query.first() languages = display_settings.announce.split(',') tickets_to_remove = Serial.query.filter( Serial.p == True, Serial.number.in_(self.cached)) tickets_to_cache = Serial.query.filter(Serial.p == False, Serial.number != 100, not_(Serial.number.in_(self.cached)))\ .order_by(Serial.timestamp)\ .limit(self.limit) for ticket in tickets_to_cache: success = False for language in languages: try: gTTs.say( language, self.format_announcement_text( ticket, aliases, language, display_settings.prefix)) success = True except Exception as exception: log_error(exception) if success: self.cached.append(ticket.number) # TODO: Use a proper logger to integrate with gevent's ongoing one print(f'Cached TTS {ticket.number}') # NOTE: Remove the processed tickets from cache stack for ticket in tickets_to_remove: self.cached.remove(ticket.number) # NOTE: cache stack is adhereing to the limit to avoid overflow self.cached = self.cached[:self.limit] sleep(self.interval)
def create_db(app, testing=False): ''' Creating all non-existing tables and load initial data. Parameters ---------- app: Flask app app to use its context to create tables and load initial data. testing: bool flag to disable migrations, mainly used during integration testing. ''' with app.app_context(): if not os.path.isfile(absolute_path(app.config.get('DB_NAME'))): db.create_all() else: try: database_upgrade(directory=MIGRATION_FOLDER) except Exception as exception: if not isinstance(exception, OperationalError): log_error(exception, quiet=os.name == 'nt') create_default_records()
def page_not_found(error): ''' Adding error handlers on main app instance. ''' if getattr(error, 'code', None) == 413: flash('Error: file uploaded is too large ', 'danger') if current_user.is_authenticated: return redirect(url_for('cust_app.multimedia', nn=1)) return redirect(url_for('core.root')) getattr(error, 'code', None) != 404 and log_error(error) flash('Error: something wrong , or the page is non-existing', 'danger') return redirect(url_for('core.root'))
def serial(t_id, office_id=None): ''' generate a new ticket and print it. ''' windows = os.name == 'nt' form = forms.Touch_name(session.get('lang')) task = data.Task.get(t_id) office = data.Office.get(office_id) touch_screen_stings = data.Touch_store.get() ticket_settings = data.Printer.get() settings = data.Settings.get() printed = not touch_screen_stings.n numeric_ticket_form = ticket_settings.value == 2 name_or_number = form.name.data or None if not task: flash('Error: wrong entry, something went wrong', 'danger') return redirect(url_for('core.root')) # NOTE: if it is registered ticket, will display the form if not form.validate_on_submit() and not printed: return render_template('touch.html', title=touch_screen_stings.title, tnumber=numeric_ticket_form, ts=touch_screen_stings, bgcolor=touch_screen_stings.bgcolor, a=4, done=False, page_title='Touch Screen - Enter name ', form=form, dire='multimedia/', alias=data.Aliases.query.first(), office_id=office_id) # NOTE: Incrementing the ticket number from the last generated ticket globally next_number = data.Serial.query.order_by(data.Serial.number.desc())\ .first().number + 1 office = office or task.least_tickets_office() if printed: current_ticket = getattr( data.Serial.all_office_tickets(office.id).first(), 'number', None) common_arguments = (f'{office.prefix}.{next_number}', f'{office.prefix}{office.name}', data.Serial.all_office_tickets(office.id).count(), task.name, f'{office.prefix}.{current_ticket}') try: if windows or settings.lp_printing: (print_ticket_cli_ar if ticket_settings.langu == 'ar' else print_ticket_cli)(ticket_settings.name, *common_arguments, language=ticket_settings.langu, windows=windows, unix=not windows) else: printer = assign(ticket_settings.vendor, ticket_settings.product, ticket_settings.in_ep, ticket_settings.out_ep) (printit_ar if ticket_settings.langu == 'ar' else printit)( printer, *common_arguments, lang=ticket_settings.langu, scale=ticket_settings.scale) except Exception as exception: flash('Error: you must have available printer, to use printed', 'danger') flash('Notice: make sure that printer is properly connected', 'info') if windows: flash( 'Notice: Make sure to make the printer shared on the local network', 'info') elif 'linux' in platform: flash( 'Notice: Make sure to execute the command `sudo gpasswd -a $(users) lp` and ' 'reboot the system', 'info') log_error(exception) return redirect(url_for('core.root')) db.session.add( data.Serial(number=next_number, office_id=office.id, task_id=task.id, name=name_or_number, n=not printed)) db.session.commit() return redirect(url_for('core.touch', a=1, office_id=office_id))