# Welcome to the LittlePrynter's source code. # This program expose a web interface, with user authentification, that makes it possible to print messages from the web. # It also exposes a API, making it possible to print and interface with much of the printer's abilities. # We first define the connection to the printer itself, # Then we build the API around Flask, # Then we build the web interface, using the simple Jinja2 templating. # Following are the librairies we import, from flask import Flask, request, render_template, flash, abort, redirect, url_for, make_response, jsonify # Used for the web framework from flask_limiter import Limiter from flask_limiter.util import get_remote_address from printer import Printer # The wrapper for the printer class from web import Web # Wrapper for the web routes and API import toml # Used for the config file parsing import pprint # To pretty print JSON import time # To sleep import os # For VARS from the shell. # Variables # Load the configuration file try: configuration_file = toml.load("configuration/config.toml") except TypeError : print("Unable to load the config file: invalid type or is a list containing invalid types") exit(-1) except toml.TomlDecodeError: print("An error occured while decoding the file") exit(-1) except Exception as e: print("Error while loading file : " + str(e)) # Define the USB connections here. vendor_id = configuration_file["printer"]["vendor_id"] device_id = configuration_file["printer"]["device_id"] # Output the config file if os.getenv('LIPY_DEBUG') == True: pprint.pprint(configuration_file) # We define the app module used by Flask app = Flask(__name__) app.secret_key = configuration_file["secrets"]["flask_secret_key"] # Printer connection # Uses the class defined in the printer.py file printer = Printer(app,0x04b8, 0x0e28) printer.init_printer() # Web routes web = Web(app, printer) limiter = Limiter( app, key_func=get_remote_address, default_limits=["200 per day", "50 per hour"] ) @app.route('/') @limiter.limit("1/second", override_defaults=False) def index(): return render_template('index.html') # API routes # The api has the following methods # api/print/{sms,img,letter,qr,barcode} # api/auth/{login,logout} # api/status/{paper,ping,stats} # If you just call the api route, you get a help back. @app.route('/api') @app.route('/api/print') @limiter.limit("1/second", override_defaults=False) def api_index(): return render_template("api.html") @app.route('/api/print/sms', methods=['POST']) @limiter.limit("2/minute", override_defaults=False) def api_print_sms(): try: txt = request.form["txt"] sign = request.form["signature"] except Exception as e: flash(e) redirect(url_for('index')) flash(web.print_sms(txt,sign)) return redirect(url_for('index')) @app.route('/api/print/image', methods=['POST']) @limiter.limit("2/minute", override_defaults=False) def api_print_image(): flash(web.print_image()) return "print image" @app.route('/login') @limiter.limit("1/second", override_defaults=False) def login_page(): # web.login(username,password) return render_template("index.html") @app.route('/logout') @limiter.limit("1/second", override_defaults=False) def logout_page(): # web.logout(username, password) return render_template("index.html") @app.errorhandler(429) def ratelimit_handler(e): flash("Rate limit reached, please slow down :) ( Currently at "+ e.description + ")", 'error') return render_template('index.html') @app.route("/ping") @limiter.exempt def ping(): return "PONG"