Infrastrukturní úklid: zamčené závislosti, verze schématu i binárky #12
No files matched your search
@@ -106,6 +106,10 @@ schématu ještě nepsala, se poznají podle nuly a orazítkují se. Databázi
|
|||||||
založenou novější verzí počitadla appka odmítne otevřít, místo aby ji tiše
|
založenou novější verzí počitadla appka odmítne otevřít, místo aby ji tiše
|
||||||
rozbila.
|
rozbila.
|
||||||
|
|
||||||
|
Obsluhuje to `waitress` — čistě pythonní WSGI server, který se zabalí do
|
||||||
|
binárky stejně snadno jako zbytek. Vestavěný server Flasku by pod úvodní
|
||||||
|
hlášku vysypal varování, že takhle se to nemá, a měl by pravdu.
|
||||||
|
|
||||||
Počítá se s domácí sítí — appka nemá přihlašování a kdokoli na stejné WiFi
|
Počítá se s domácí sítí — appka nemá přihlašování a kdokoli na stejné WiFi
|
||||||
může zapisovat.
|
může zapisovat.
|
||||||
|
|
||||||
|
|||||||
+10
-3
@@ -1,10 +1,10 @@
|
|||||||
"""Aby čeština prošla i tam, kde konzole čeká něco jiného."""
|
"""Aby výstup prošel i tam, kde ho nikdo nečeká na konzoli."""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def utf8() -> None:
|
def utf8() -> None:
|
||||||
"""Přepne standardní výstup na UTF-8.
|
"""Přepne standardní výstup na UTF-8 a na řádkové bufferování.
|
||||||
|
|
||||||
Windows sahá po historické kódové stránce (cp1252, cp852) všude, kde
|
Windows sahá po historické kódové stránce (cp1252, cp852) všude, kde
|
||||||
výstup není konzole — přesměrovaný do souboru, puštěný ze skriptu, ve
|
výstup není konzole — přesměrovaný do souboru, puštěný ze skriptu, ve
|
||||||
@@ -14,7 +14,14 @@ def utf8() -> None:
|
|||||||
Na konzoli i na ostatních systémech je UTF-8 dávno výchozí a tohle je
|
Na konzoli i na ostatních systémech je UTF-8 dávno výchozí a tohle je
|
||||||
tam prázdná operace. `errors="replace"` je pojistka pro zbylé případy:
|
tam prázdná operace. `errors="replace"` je pojistka pro zbylé případy:
|
||||||
rozsypaný háček je pořád lepší než spadlý server.
|
rozsypaný háček je pořád lepší než spadlý server.
|
||||||
|
|
||||||
|
Řádkové bufferování řeší druhou půlku téhož problému. Mimo konzoli
|
||||||
|
Python drží výstup v bloku a pouští ho, až se naplní nebo až program
|
||||||
|
skončí — jenže server neskončí, ten běží. Kdo si ho pustí na pozadí
|
||||||
|
s výpisem do souboru, našel by tam prázdno; přesně to dělá zkouška
|
||||||
|
binárky v CI. Pár řádek hlášky za to bufferovat nemá cenu.
|
||||||
"""
|
"""
|
||||||
for stream in (sys.stdout, sys.stderr):
|
for stream in (sys.stdout, sys.stderr):
|
||||||
if hasattr(stream, "reconfigure"):
|
if hasattr(stream, "reconfigure"):
|
||||||
stream.reconfigure(encoding="utf-8", errors="replace")
|
stream.reconfigure(encoding="utf-8", errors="replace",
|
||||||
|
line_buffering=True)
|
||||||
+18
-1
@@ -9,10 +9,12 @@ class Proud:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.encoding = "cp1252"
|
self.encoding = "cp1252"
|
||||||
self.errors = "strict"
|
self.errors = "strict"
|
||||||
|
self.line_buffering = False
|
||||||
|
|
||||||
def reconfigure(self, encoding, errors):
|
def reconfigure(self, encoding, errors, line_buffering=False):
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
self.errors = errors
|
self.errors = errors
|
||||||
|
self.line_buffering = line_buffering
|
||||||
|
|
||||||
|
|
||||||
def test_vystup_se_prepne_na_utf8(monkeypatch):
|
def test_vystup_se_prepne_na_utf8(monkeypatch):
|
||||||
@@ -24,6 +26,7 @@ def test_vystup_se_prepne_na_utf8(monkeypatch):
|
|||||||
|
|
||||||
assert (out.encoding, out.errors) == ("utf-8", "replace")
|
assert (out.encoding, out.errors) == ("utf-8", "replace")
|
||||||
assert (err.encoding, err.errors) == ("utf-8", "replace")
|
assert (err.encoding, err.errors) == ("utf-8", "replace")
|
||||||
|
assert out.line_buffering and err.line_buffering
|
||||||
|
|
||||||
|
|
||||||
def test_cestina_projde_i_pres_cp1252(monkeypatch):
|
def test_cestina_projde_i_pres_cp1252(monkeypatch):
|
||||||
@@ -46,3 +49,17 @@ def test_proud_bez_reconfigure_se_prezije(monkeypatch):
|
|||||||
monkeypatch.setattr(console.sys, "stderr", object())
|
monkeypatch.setattr(console.sys, "stderr", object())
|
||||||
|
|
||||||
console.utf8()
|
console.utf8()
|
||||||
|
|
||||||
|
|
||||||
|
def test_hlaska_je_v_souboru_hned(tmp_path, monkeypatch):
|
||||||
|
"""Server běží dál, takže na vyprázdnění bufferu při konci se čekat nedá."""
|
||||||
|
cesta = tmp_path / "server.log"
|
||||||
|
with cesta.open("w", encoding="utf-8") as soubor:
|
||||||
|
monkeypatch.setattr(console.sys, "stdout", soubor)
|
||||||
|
monkeypatch.setattr(console.sys, "stderr", soubor)
|
||||||
|
|
||||||
|
console.utf8()
|
||||||
|
print("Počitadlo je dostupné na:", file=console.sys.stdout)
|
||||||
|
|
||||||
|
# Bez zavření souboru — přesně jako u běžícího serveru.
|
||||||
|
assert "Počitadlo je dostupné" in cesta.read_text(encoding="utf-8")
|
||||||
@@ -17,6 +17,7 @@ import qrcode
|
|||||||
from flask import (Flask, abort, g, redirect, render_template, request,
|
from flask import (Flask, abort, g, redirect, render_template, request,
|
||||||
url_for)
|
url_for)
|
||||||
from markupsafe import Markup, escape
|
from markupsafe import Markup, escape
|
||||||
|
from waitress import serve
|
||||||
|
|
||||||
import console
|
import console
|
||||||
import net
|
import net
|
||||||
@@ -353,4 +354,9 @@ if __name__ == "__main__":
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
announce()
|
announce()
|
||||||
app.run(host="0.0.0.0", port=PORT, threaded=True)
|
|
||||||
|
# Ne vestavěný server Flasku: ten pod úvodní hlášku vysype červené
|
||||||
|
# varování, že takhle se to nemá, a má pravdu. Waitress je čistě
|
||||||
|
# pythonní, takže se zabalí do binárky bez řečí, a osm vláken pobere
|
||||||
|
# telefony u stolu i tabuli, která se doptává každé dvě vteřiny.
|
||||||
|
serve(app, host="0.0.0.0", port=PORT, threads=8)
|
||||||
Reference in new issue
Block a user