Update draft to little prynter article

This commit is contained in:
N07070 2022-10-28 11:07:42 +02:00
parent 76354960a4
commit f53b14f38b
1 changed files with 34 additions and 7 deletions

View File

@ -50,21 +50,23 @@ After a few days of hacking, I finally had a complete photomaton that could be a
There was Little Prynter.
### How to code works
### How the code works
The program starts thanks to a bash script, `run.sh`, that starts a Python virtual environnement, install the dependencies and runs the server with the good environnement variable.
The program starts thanks to a bash script, `run.sh`, that starts a Python virtual environnement, install the dependencies and runs the server with the good environnement variables.
It will in turn, call the flask command, that will launch a developpement server with the `main.py` file as it's starting point.
This fille will define the routes that will be accessible on the server.
This file will define the routes that will be accessible on the server.
The `main.py` file will start by loading the configuration file, and then start trying to connect to the printer via the `Printer` class.
The `main.py` file will start by loading the configuration file, and then try to connect to the printer via the `Printer` class.
```python
configuration_file = toml.load("configuration/config.toml")
```
The tricky thing about connecting via USB is that you need the USB vendor and device ID loaded, but they are encoded in hexadecimal. So we pass thoses options to the Printer class, that will initiate a new global connection to the Printer. It's faster this way, but we could open a new connection each time instead. The continus connexion sometimes hangs up, making it necessary to restart the software.
The tricky thing about connecting via USB is that you need the USB vendor and device ID loaded, but they are encoded in hexadecimal. So we pass thoses options to the Printer class, that will initiate a new global connection to the Printer.
It's faster this way, but we could open a new connection each time instead, in the `Web` class for example. The continus connexion sometimes hangs up, making it necessary to restart the software. On the other hand, we might get a concurent connection to the printer if two people try to print at the same time. Implementing a queue could solve this.
```python
# Printer connection
@ -73,9 +75,34 @@ printer = Printer(app,0x04b8, 0x0e28)
printer.init_printer()
```
This class will mainly load the `escpos` library that does all the heavy lifting will connecting to the printer. To note, the library, at time of writing, did not have the exact printer I has in it's database, but instead a close relative of it, which works _well enough_. It also defines to methods to print texte and an image.
This class will mainly load the `escpos` library that does all the heavy lifting will connecting to the printer. It also defines to methods to print texte and an image. To note, the library, at time of writing, did not have the exact printer I have in it's database, but instead a close relative of it, which works _well enough_.
The web interface part is handle just after, in a `Web` class that makes heavy use of Flask. I'm using a Python framework called Flask. It makes it easy to run a web server. I've learned how to write it thanks to [Miguel Grinberg's Flask Mega Tutorial](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world).
The web interface part is handled just after, in a `Web` class that makes heavy use of Flask, a Python framework for easily bulding web servers. I've learned how to write it thanks to [Miguel Grinberg's Flask Mega Tutorial](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world), it's great and you should read it if you plan on writing anything based in Flask.
The web class handles calling the printing of the images via the `Printer` class I mentionned earlier. It's also goint to call the `User` class to manage the login and logout of users, if needed.
```python
def print_sms(self, texte, sign: str):
self.app.logger.debug("Printing : " + str(texte) + " from " + str(sign))
if not os.getenv('LIPY_DEBUG'):
time.sleep(1)
return self.printer.print_sms(texte, sign)
```
Finally, the `Main` class defines the routes that are callable, such as the main page ;
```python
@app.route('/')
@limiter.limit("1/second", override_defaults=False)
def index():
app.logger.debug("Loading index")
return render_template('index.html')
```
You can see that we are rate limiting each route thanks to the `limiter` package, that extends Flask itself. We are also using Jinja2 to manage the rendering of the web pages, which use normal HTML and CSS, altought we use BootStrap 3 for the user interface.
The Jinja 2 templates ( or HTML pages ) can be found in the `template/` folder. Some are partials, mening that they are reused in other templates.
A few pictures to show it off ;