commit 8c1647eb13fc63b63c89b3c0832b1e18e236fd10 Author: Antone Date: Mon Sep 15 00:15:49 2025 +0300 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6b56895 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.env +*venv +__pycache__ \ No newline at end of file diff --git a/config.py b/config.py new file mode 100644 index 0000000..695a8e1 --- /dev/null +++ b/config.py @@ -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 diff --git a/printer.py b/printer.py new file mode 100644 index 0000000..88c7139 --- /dev/null +++ b/printer.py @@ -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() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..0477a9a --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +escpos +flask +pillow diff --git a/server.py b/server.py new file mode 100644 index 0000000..b0218ae --- /dev/null +++ b/server.py @@ -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) diff --git a/static/config.html b/static/config.html new file mode 100644 index 0000000..8bdade2 --- /dev/null +++ b/static/config.html @@ -0,0 +1,35 @@ + + + + + + + P80 printer webpage configuration + + + + + + +
+
+
+
+ +
+
+ +
+
+
+ +
+ + + \ No newline at end of file diff --git a/static/config.js b/static/config.js new file mode 100644 index 0000000..31e4911 --- /dev/null +++ b/static/config.js @@ -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() +} \ No newline at end of file diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..2ccde8f --- /dev/null +++ b/static/index.html @@ -0,0 +1,22 @@ + + + + + + + P80 printer webpage + + + + + +
+
+ + + \ No newline at end of file diff --git a/static/index.js b/static/index.js new file mode 100644 index 0000000..e69de29 diff --git a/static/style.css b/static/style.css new file mode 100644 index 0000000..e69de29