init
This commit is contained in:
		
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| *.env | ||||
| *venv | ||||
| __pycache__ | ||||
							
								
								
									
										38
									
								
								config.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								config.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| import json | ||||
| import printer | ||||
|  | ||||
|  | ||||
| class PrinterConfig: | ||||
|     editables = {"printer_address", "printer_port"} | ||||
|     required_params = {"printer_address"} | ||||
|  | ||||
|     def __init__(self): | ||||
|         self.printer_address = None | ||||
|         self.printer_port = 9100 | ||||
|         self.printer_profile = "RP-F10-80mm" | ||||
|         self.__printer = None | ||||
|  | ||||
|     def save(self): | ||||
|         with open("config.json", "w", encoding="utf-8") as ofd: | ||||
|             json.dump(self.__dict__, ofd, ensure_ascii=False) | ||||
|  | ||||
|     def load(self): | ||||
|         with open("config.json", "r", encoding="utf-8") as ifd: | ||||
|             self.__dict__ = json.load(ifd) | ||||
|  | ||||
|     @property | ||||
|     def complete(self): | ||||
|         for param in self.required_params: | ||||
|             if getattr(self, param) is None: | ||||
|                 return False | ||||
|         return True | ||||
|  | ||||
|     @property | ||||
|     def printer(self): | ||||
|         if self.__printer is None: | ||||
|             self.__printer = printer.Printer( | ||||
|                 address=self.printer_address, | ||||
|                 port=self.printer_port, | ||||
|                 profile=self.printer_profile, | ||||
|             ) | ||||
|         return self.printer | ||||
							
								
								
									
										17
									
								
								printer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								printer.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| from escpos.printer import Network | ||||
|  | ||||
| class Printer: | ||||
|     def __init__(self, address: str, port: int = 9070, profile="RP-F10-80mm"): | ||||
|         self.address = address | ||||
|         self.port = port | ||||
|         self.profile = profile | ||||
|         self.printer = Network(host = self.address, port=self.port, profile=profile) | ||||
|  | ||||
|     def test_connection(self): | ||||
|         return self.printer.is_online() | ||||
|  | ||||
|     def print_text(self, text: str): | ||||
|         # todo text properties via printer.set() | ||||
|         self.printer.text(text) | ||||
|         self.printer.ln(2) | ||||
|         self.printer.cut() | ||||
							
								
								
									
										3
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| escpos | ||||
| flask | ||||
| pillow | ||||
							
								
								
									
										104
									
								
								server.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								server.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| from os import environ | ||||
| import argparse | ||||
| from flask import Flask, request, make_response, send_from_directory, jsonify | ||||
| from config import PrinterConfig | ||||
|  | ||||
| argument_parser = argparse.ArgumentParser() | ||||
| argument_parser.add_argument("--address", type=str, required=False, default="0.0.0.0") | ||||
| argument_parser.add_argument("--port", type=int, required=False, default=8005) | ||||
|  | ||||
| args = argument_parser.parse_args() | ||||
|  | ||||
| printer_config = PrinterConfig() | ||||
| app = Flask(__name__) | ||||
|  | ||||
|  | ||||
| @app.route("/") | ||||
| def index_route(): | ||||
|     return send_from_directory("static", "index.html") | ||||
|  | ||||
|  | ||||
| @app.route("/config", methods=["GET", "POST"]) | ||||
| def config_route(): | ||||
|     request_type = None | ||||
|     if "Accept" in request.headers: | ||||
|         if "text/html" in request.headers["Accept"]: | ||||
|             request_type = "html" | ||||
|         elif "application/json" in request.headers["Accept"]: | ||||
|             request_type = "json" | ||||
|  | ||||
|     print(request_type) | ||||
|     if request.method == "GET" and request_type == "html": | ||||
|         # return config html page | ||||
|         return send_from_directory("static", "config.html") | ||||
|     elif request.method == "GET" and request_type == "json": | ||||
|         # render config as JSON | ||||
|         print(get_config()) | ||||
|         return jsonify(get_config()) | ||||
|     elif request.method == "POST" and request.is_json: | ||||
|         # accept JSON form with new parameters | ||||
|         errors = {"critical": False, "errors": {}} | ||||
|         try: | ||||
|             request_data = request.json | ||||
|             print(request_data) | ||||
|         except Exception: | ||||
|             errors["errors"]["json"] = "Could not decode message as json" | ||||
|             errors["critical"] = True | ||||
|          | ||||
|         request_params = {} | ||||
|         if "address" in request_data: | ||||
|             request_params["address"] = request_data["address"] | ||||
|         if "port" in request_data: | ||||
|             port = request_data["port"] | ||||
|             if isinstance(port, int) and 0 < port <= 65535: | ||||
|                 request_params["port"] = port | ||||
|             else: | ||||
|                 errors["errors"]["parseint"] = "Could not parse port number as an integer" | ||||
|                 errors["critical"] = True | ||||
|          | ||||
|         response = jsonify(errors) | ||||
|         if errors["critical"]: | ||||
|             response.status_code = 422 | ||||
|         else: | ||||
|             response.status_code = 200 | ||||
|             set_config(**request_params) | ||||
|         return response | ||||
|  | ||||
|  | ||||
| def get_config(): | ||||
|     return { | ||||
|         "address": printer_config.printer_address, | ||||
|         "port": printer_config.printer_port, | ||||
|         "profile": printer_config.printer_profile, | ||||
|         "can_print": can_print(), | ||||
|     } | ||||
|  | ||||
|  | ||||
| def set_config(address: str = None, port: int = None): | ||||
|     if address is None: | ||||
|         printer_config.printer_address = None | ||||
|     else: | ||||
|         printer_config.printer_address = address | ||||
|     if port is None: | ||||
|         printer_config.printer_port = 9100 | ||||
|     else: | ||||
|         printer_config.printer_port = port | ||||
|  | ||||
|  | ||||
| def can_print(): | ||||
|     return printer_config.complete | ||||
|  | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     try: | ||||
|         printer_config.load() | ||||
|     except FileNotFoundError: | ||||
|         pass | ||||
|  | ||||
|     try: | ||||
|         app.run(host=args.address, port=args.port) | ||||
|     except KeyboardInterrupt: | ||||
|         pass | ||||
|  | ||||
|     printer_config.save() | ||||
|     exit(0) | ||||
							
								
								
									
										35
									
								
								static/config.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								static/config.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|  | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>P80 printer webpage configuration</title> | ||||
|     <script src="static/config.js"></script> | ||||
| </head> | ||||
|  | ||||
| <body onload="render_config();"> | ||||
|     <div class="navbar"> | ||||
|         <ul> | ||||
|             <a href="/">Print</a> | ||||
|             <a href="/config">Configuration</a> | ||||
|         </ul> | ||||
|     </div> | ||||
|  | ||||
|     <div class="container" display="block"> | ||||
|         <form> | ||||
|             <label for="address">Address:</label><br> | ||||
|             <input type="text" id="address" name="address" title="Printer network address (ip/hostname)" | ||||
|                 maxlength="30"><br> | ||||
|  | ||||
|             <label for="port">Port:</label><br> | ||||
|             <input type="text" id="port" name="port" pattern="\d{1,5}" title="Port number (9100 by default)"><br> | ||||
|  | ||||
|             <label for="profile">Profile:</label><br> | ||||
|             <input type="text" id="profile" name="profile" title="Printer profile, fixed value for now" readonly><br> | ||||
|         </form> | ||||
|         <button type="submit" onclick="send_config()">Update config</button> | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										36
									
								
								static/config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								static/config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| async function get_config() { | ||||
|     response = await fetch("/config", {method: "GET", headers: {"Accept": "application/json"}}) | ||||
|     if (! response.ok){ | ||||
|         throw Error("config data request error: " + await response.text()) | ||||
|     } | ||||
|     return response.json() | ||||
| } | ||||
|  | ||||
| async function render_config(){ | ||||
|     params = await get_config() | ||||
|     for (par of Object.keys(params)) { | ||||
|         if (params.par == null) { | ||||
|             params.par = "" | ||||
|         } | ||||
|     } | ||||
|     const {address, port, profile} = params | ||||
|     document.getElementById("address").value = address | ||||
|     document.getElementById("port").value = port | ||||
|     document.getElementById("profile").value = profile | ||||
| } | ||||
|  | ||||
| async function send_config() { | ||||
|     address_value = document.getElementById("address").value | ||||
|     port_value = document.getElementById("port").value | ||||
|     if (port_value == ""){ | ||||
|         port_value = null | ||||
|     } | ||||
|     else{ | ||||
|         port_value = parseInt(port_value) | ||||
|     } | ||||
|          | ||||
|      | ||||
|     response = await fetch("/config", {method: "POST", headers: {"Accept": "application/json", "Content-Type": "application/json"}, | ||||
|         body: JSON.stringify({"address": address_value, "port": port_value, })}) | ||||
|     document.location.reload() | ||||
| } | ||||
							
								
								
									
										22
									
								
								static/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								static/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|  | ||||
| <head> | ||||
|     <meta charset="UTF-8"> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||
|     <title>P80 printer webpage</title> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="navbar"> | ||||
|         <ul> | ||||
|             <a href="/">Print</a> | ||||
|             <a href="/config">Configuration</a> | ||||
|         </ul> | ||||
|     </div> | ||||
|  | ||||
|     <div class="container" display="block"> | ||||
|     </div> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
							
								
								
									
										0
									
								
								static/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								static/index.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								static/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								static/style.css
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user