Commit 5da2cb05 by Luciano Barletta

fix issue #2041

1 parent 9ac32563
......@@ -2,4 +2,5 @@ __pycache__
.vscode
*.log
test.py
*.pdf
\ No newline at end of file
*.pdf
users.json
\ No newline at end of file
#-*- coding: utf-8 -*-
from flask import Flask, render_template, request, url_for
from flask import Flask, render_template, request, url_for, make_response, redirect
from iselenium import SeleniumInterface as SI
import random, json
import random, json, os
app = Flask(__name__)
def create():
if not os.path.exists("users.json"):
with open("users.json", "+w") as f:
f.write("{}")
def usersave(usr, psw):
create()
content = ""
with open("users.json", "r") as u:
content = u.read()
with open("users.json", "w") as u:
try:
content = json.loads(content)
except:
content = {}
content[usr] = psw
u.write( json.dumps(content) )
def userget(usr):
create()
content = ""
with open("users.json", "r") as u:
content = u.read()
try:
return json.loads(content)[usr]
except:
return None
@app.route('/')
def main():
return render_template(
"form.html",
bypass = False
)
if "login" in request.cookies:
return render_template(
"form.html",
bypass = False
)
else:
return redirect(url_for("login"))
@app.route('/login', methods = ['GET', 'POST'])
def login():
if request.method == "GET":
return render_template(
"login.html"
)
else:
try:
s = SI(SI.Chrome)
r = make_response(
json.dumps(
login(
request.json['usuario'],
request.json['contrasena'],
s
)
)
)
r.set_cookie(
"login",
request.json['usuario'],
60 * 60 * 8,
httponly = True
)
usersave(
request.json['usuario'],
request.json['contrasena']
)
s.driver.close()
return r
except:
s.driver.close()
return "Error en el login"
@app.route('/manual')
def manual():
......@@ -21,6 +90,9 @@ def manual():
@app.route('/pdf', methods = ['POST'])
def pdf():
if "login" not in request.cookies:
return redirect(url_for("login"))
d = request.json
plate = d['header']['patente']
s = SI(SI.Chrome)
......@@ -37,31 +109,36 @@ def pdf():
answer['header']['patente'] = plate.upper()
try:
answer = login(
d['credenciales']['usuario'],
d['credenciales']['contrasena'],
s,
answer
login(
request.cookies["login"],
userget(
request.cookies["login"]
),
s
)
except:
return "Error en el login."
s.driver.close()
return f"Error en el login"
try:
answer = gototec(s, answer)
except:
s.driver.close()
return f"Error yendo a las especificaciones técnicas del dominio '{plate}'."
try:
answer = readdata(s, answer)
except:
return f"Error leyendo datos de la patente '{plate}'."
#try:
answer = readdata(s, answer)
#except:
#s.driver.close()
#return f"Error leyendo datos de la patente '{plate}'."
try:
answer = rnddata(answer)
except:
s.driver.close()
return f"Error completando datos extra de la patente '{plate}'."
print(answer)
s.driver.close()
return json.dumps(answer)
def login(u, p, s, r):
def login(u, p, s):
s.get("https://rto.cent.gov.ar/rto")
login = s.find(SI.By.NAME, "j_username")
......@@ -72,14 +149,12 @@ def login(u, p, s, r):
button = s.find(SI.By.ID, "submit")
button.click()
reach = lambda s: s.find(SI.By.NAME, "j_username")
login = attempt_do(reach, default = "?")(s)
login = _attempt(lambda s: s.find(SI.By.NAME, "j_username"), "?")(s)
# login succeeded
if login == "?":
return r
return True
# still in login page
else:
......@@ -116,36 +191,42 @@ def readdata(s, r):
reach = lambda id: lambda s: s.readInput( s.find(s.By.ID, id) )
# alineacion
r['alineador']['eje_delantero'] = empty_for_question(attempt_do(reach("deriva"), default = "?")(s))
r['alineador']['eje_delantero'] = _e2q(_attempt( reach("deriva"), "?" )(s))
# suspension
sus = r['suspension']
for i in range(2):
sus = {}
sus[f'peso_estatico_{i + 1}'] = empty_for_question(attempt_do(reach(f"pesoBascula-{i}"), default = "?")(s))
# si valores de rendimiento son numeros, leer el peso
if sus[f'rendimiento_izquierdo_{i + 1}'].isnumeric() or sus[f'rendimiento_derecho_{i + 1}'].isnumeric():
sus[f'peso_estatico_{i + 1}'] = _e2q(_attempt( reach(f"pesoBascula-{i}"), "?" )(s))
else:
sus[f'rendimiento_izquierdo_{i + 1}'] = "?"
sus[f'rendimiento_derecho_{i + 1}'] = "?"
sus[f'peso_estatico_{i + 1}'] = "?"
r['suspension'].update(sus)
r['suspension'].update(sus)
# frenos
for i in range(4):
fre = {}
fre[f'peso_estatico_{i + 1}'] = empty_for_question(attempt_do(reach(f"pesoBascula-{i}"), default = "?")(s))
fre[f'fuerza_izquierda_{i + 1}'] = empty_for_question(attempt_do(reach(f"fuerzaIzq-{i}"), default = "?")(s))
fre[f'fuerza_derecha_{i + 1}'] = empty_for_question(attempt_do(reach(f"fuerzaDer-{i}"), default = "?")(s))
fre[f'peso_estatico_{i + 1}'] = _e2q(_attempt( reach(f"pesoBascula-{i}"), "?" )(s))
fre[f'fuerza_izquierda_{i + 1}'] = _e2q(_attempt( reach(f"fuerzaIzq-{i}"), "?" )(s))
fre[f'fuerza_derecha_{i + 1}'] = _e2q(_attempt( reach(f"fuerzaDer-{i}"), "?" )(s))
r['frenos'].update(fre)
# freno trasero
r['trasero']['peso_estatico'] = empty_for_question(attempt_do(reach(f"pesoBasculaEst-0"), default = "?")(s))
r['trasero']['fuerza_izquierda'] = empty_for_question(attempt_do(reach(f"fuerzaIzqEst-0"), default = "?")(s))
r['trasero']['fuerza_derecha'] = empty_for_question(attempt_do(reach(f"fuerzaDerEst-0"), default = "?")(s))
r['trasero']['eje'] = empty_for_question(attempt_do(reach(f"nroEjeEst-0"), default = "?")(s))
r['trasero']['peso_estatico'] = _e2q(_attempt( reach(f"pesoBasculaEst-0"), "?" )(s))
r['trasero']['fuerza_izquierda'] = _e2q(_attempt( reach(f"fuerzaIzqEst-0"), "?" )(s))
r['trasero']['fuerza_derecha'] = _e2q(_attempt( reach(f"fuerzaDerEst-0"), "?" )(s))
r['trasero']['eje'] = _e2q(_attempt( reach(f"nroEjeEst-0"), "?" )(s))
# gases y humos
r['gaseshumos']['opacidad_logaritmica'] = empty_for_question(attempt_do(reach(f"opacidadLogaritmica"), default = "?")(s))
r['gaseshumos']['co'] = empty_for_question(attempt_do(reach(f"cantCO"), default = "?")(s))
r['gaseshumos']['hc'] = empty_for_question(attempt_do(reach(f"cantHC"), default = "?")(s))
r['gaseshumos']['opacidad_logaritmica'] = _e2q(_attempt( reach(f"opacidadLogaritmica"), "?" )(s))
r['gaseshumos']['co'] = _e2q(_attempt( reach(f"cantCO"), "?" )(s))
r['gaseshumos']['hc'] = _e2q(_attempt( reach(f"cantHC"), "?" )(s))
return r
......@@ -168,7 +249,7 @@ def rnddata(r):
return r
# Executes the lambda with the arguments, with try except
def attempt_do(f, default = "", error = ""):
def _attempt(f, default = "", error = ""):
def inner(*args, **kwargs):
try:
return f(*args, **kwargs)
......@@ -178,7 +259,7 @@ def attempt_do(f, default = "", error = ""):
return default
return inner
def empty_for_question(string):
def _e2q(string):
return "?" if string == "" else string
# Inicio del servicio
......
"use strict";
function collectToSearch() {
f = document.getElementById("form");
inputs = f.getElementsByTagName("input");
const f = document.getElementById("form");
const inputs = f.getElementsByTagName("input");
const defecto = document.getElementsByName("defecto")[0].value;
data = {};
let data = {};
function BadInputException(input) {
this.error = "badinput";
......@@ -16,17 +19,15 @@ function collectToSearch() {
throw BadInputException(input);
}
sub = input.getAttribute("sub");
const sub = input.getAttribute("sub");
if ( (sub in data) === false ) {
data[sub] = {}
}
data[sub][input.name] = input.value;
data[sub][input.name] = (input.value === "" ? defecto : input.value);
});
message("Espere...");
console.log(data);
const obj = {
"url" : "/pdf",
"contentType" : "application/json",
......@@ -49,21 +50,21 @@ function collectToSearch() {
"ontimeout" : (response) => message("La conexión tardó demasiado.")
}
ajax = new Ajax(obj);
let ajax = new Ajax(obj);
ajax.post();
}
function collectToConvert() {
r = document.getElementById("results")
inputs = r.getElementsByTagName("input");
const r = document.getElementById("results")
const inputs = r.getElementsByTagName("input");
data = {};
defecto = document.getElementsByName("defecto")[0].value;
let data = {};
const defecto = document.getElementsByName("defecto")[0].value;
Array.from(inputs).forEach(input => {
if (input.name == "defecto") return;
sub = input.getAttribute("sub");
const sub = input.getAttribute("sub");
if ((sub in data) === false) {
data[sub] = {}
}
......@@ -81,13 +82,13 @@ function message(msg) {
}
function fillResults(results) {
r = document.getElementById("results")
inputs = r.getElementsByTagName("input");
const r = document.getElementById("results")
const inputs = r.getElementsByTagName("input");
Array.from(inputs).forEach(input => {
if (input.name == "defecto") return;
sub = input.getAttribute("sub");
const sub = input.getAttribute("sub");
input.value = results[sub][input.name];
});
}
\ No newline at end of file
function login() {
message("Espere...");
const usr = document.getElementsByName("usuario")[0];
const psw = document.getElementsByName("contrasena")[0];
function BadInputException(input) {
this.error = "badinput";
this.input = input;
}
if (usr.checkValidity() === false) {
usr.reportValidity("Por favor llene este campo");
throw BadInputException(input);
}
if (psw.checkValidity() === false) {
psw.reportValidity("Por favor llene este campo");
throw BadInputException(input);
}
const obj = {
"url": "/login",
"contentType": "application/json",
"async": true,
"data": { "usuario" : usr.value, "contrasena" : psw.value },
"success": (response) => {
console.log(response)
if (response === "true")
location.href = "/";
else
message(response);
},
"error": (response) => message(response),
"timeout": 120000,
"ontimeout": (response) => message("La conexión tardó demasiado.")
}
const ajax = new Ajax(obj);
ajax.post();
}
\ No newline at end of file
......@@ -4,11 +4,14 @@
html {
font-size: var(--FontSize);
font-family: 'CMUTypewriterTextRegular';
font-family: 'Geneva';
font-weight: normal;
font-style: normal;
color: rgb(50, 50, 50);
background-color: rgb(200, 200, 200);
}
td{
td {
text-align: center;
margin: auto;
align-content: center;
......@@ -24,6 +27,18 @@ td{
text-align: unset;
}
.DataCard {
margin: 3%;
margin-top: 2%;
margin-bottom: 4%;
border-radius: 10px;
width: 88%;
height: auto;
box-shadow: 0px 0px 15px 3px rgba(0, 0, 0, 0.5);
background-color: white;
padding: 3%;
}
.PDFButtonContainer {
margin: auto;
margin-top: 3%;
......@@ -35,12 +50,13 @@ td{
.PDFButtonContainerFixed {
position: fixed;
right: 50;
bottom: 33.33%;
right: 75;
bottom: 50%;
}
.PDFButton {
background-color: #4CAF50;
border-radius: 5px;
border: none;
color: white;
padding: 15px 32px;
......@@ -51,6 +67,7 @@ td{
}
input {
outline: none;
position: absolute;
left: 30%;
font-size: 15;
......@@ -68,7 +85,7 @@ input {
}
.MessageContainer {
background-color: rgba(150, 150, 150, 0.5);
background-color: rgba(150, 150, 150, 0.3);
width: 100%;
height: 100%;
position: fixed;
......@@ -77,11 +94,15 @@ input {
}
.Message, .MessageFixed {
color: black;
font-weight: 500;
max-width: 33%;
padding: 1%;
font-size: 20;
border: 2px solid gray;
background-color: rgb(200, 150, 250);
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
border-radius: 10px;
}
.Message {
......@@ -96,7 +117,7 @@ input {
.MessageFixed {
position: fixed;
top: 50;
right: 50;
right: 75;
}
.X {
......@@ -104,5 +125,4 @@ input {
top: 3;
right: 3;
font-weight: bolder;
font-family: Arial, Helvetica, sans-serif;
}
\ No newline at end of file
:root {
--FontSize: 25;
}
html {
font-size: var(--FontSize);
font-family: 'Geneva';
font-weight: normal;
font-style: normal;
color: rgb(50, 50, 50);
background-color: rgb(200, 200, 200);
}
td {
text-align: center;
margin: auto;
align-content: center;
width: 33.33%;
}
.header {
width: 50%;
}
.header td {
width: 50%;
text-align: unset;
}
.LoginCard {
border-radius: 10px;
text-align: center;
width: 75%;
height: 75%;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: 0px 0px 15px 3px rgba(0, 0, 0, 0.5);
background-color: white;
}
.PDFButton {
background-color: #4CAF50;
border-radius: 5px;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
}
input {
margin-top: 10%;
margin: auto;
outline: none;
font-size: 20;
border-top: none;
border-left: none;
border-right: none;
border-bottom: 2px solid gray;
font-weight: 700;
size: 30%;
text-align: center;
}
.bottom {
position: absolute;
bottom: 0;
left: 50%;
transform: translate(-50%, -50%);
}
.MessageContainer {
background-color: rgba(150, 150, 150, 0.3);
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
}
.Message,
.MessageFixed {
color: black;
font-weight: 500;
max-width: 33%;
padding: 1%;
font-size: 20;
border: 2px solid gray;
background-color: rgb(200, 150, 250);
box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.3);
border-radius: 10px;
}
.Message {
min-width: 10%;
min-height: 5%;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.MessageFixed {
position: fixed;
top: 50;
right: 50;
}
.X {
position: absolute;
top: 3;
right: 3;
font-weight: bolder;
}
\ No newline at end of file
......@@ -21,73 +21,75 @@
Pueden ser completados a mano antes de convertir a PDF.<br>
De no ser completados, se completaran automáticamente con el valor del campo 'Por defecto' al final de la página.
</div>
<h1>Datos Generales</h1>
Patente <input sub="header" type="text" name="patente">
<br>
Fecha <input sub="header" type="text" name="fecha">
<br>
<h1>Alineador</h1>
Eje Delantero <input sub="alineador" type="text" name="eje_delantero">
<br>
<h1>Suspensión</h1>
{% for eje in range(2) %}
<h3>Eje {{ eje + 1 }}</h3>
Rendimiento Izquerdo <input sub="suspension" type="text" name="rendimiento_izquierdo_{{ eje + 1 }}">
<div class="DataCard">
<h1>Datos Generales</h1>
Patente <input sub="header" type="text" name="patente">
<br>
Rendimiento Derecho <input sub="suspension" type="text" name="rendimiento_derecho_{{ eje + 1 }}">
<br>
Peso Total <input sub="suspension" type="text" name="peso_estatico_{{ eje + 1 }}">
Fecha <input sub="header" type="text" name="fecha">
<br>
<h1>Alineador</h1>
Eje Delantero <input sub="alineador" type="text" name="eje_delantero">
<br>
<h1>Suspensión</h1>
{% for eje in range(2) %}
<h3>Eje {{ eje + 1 }}</h3>
Rendimiento Izquerdo <input sub="suspension" type="text" name="rendimiento_izquierdo_{{ eje + 1 }}">
<br>
Rendimiento Derecho <input sub="suspension" type="text" name="rendimiento_derecho_{{ eje + 1 }}">
<br>
Peso Total <input sub="suspension" type="text" name="peso_estatico_{{ eje + 1 }}">
<br>
<br>
{% endfor %}
<h1>Frenos</h1>
{% for eje in range(4) %}
{% endfor %}
<h3>Eje {{ eje + 1 }}</h3>
Fuerza Izquierda <input sub="frenos" type="text" name="fuerza_izquierda_{{ eje + 1 }}">
<h1>Frenos</h1>
{% for eje in range(4) %}
<h3>Eje {{ eje + 1 }}</h3>
Fuerza Izquierda <input sub="frenos" type="text" name="fuerza_izquierda_{{ eje + 1 }}">
<br>
Fuerza Derecha <input sub="frenos" type="text" name="fuerza_derecha_{{ eje + 1 }}">
<br>
Resistencia Izquierda <input sub="frenos" type="text" name="resistencia_izquierda_{{ eje + 1 }}">
<br>
Resistencia Derecha <input sub="frenos" type="text" name="resistencia_derecha_{{ eje + 1 }}">
<br>
Ovalidad Izquierda <input sub="frenos" type="text" name="ovalidad_izquierda_{{ eje + 1 }}">
<br>
Ovalidad Derecha <input sub="frenos" type="text" name="ovalidad_derecha_{{ eje + 1 }}">
<br>
Peso Total <input sub="frenos" type="text" name="peso_estatico_{{ eje + 1 }}">
<br>
<br>
{% endfor %}
<h1>Freno Trasero</h1>
Fuerza Izquierda <input sub="trasero" type="text" name="fuerza_izquierda">
<br>
Fuerza Derecha <input sub="frenos" type="text" name="fuerza_derecha_{{ eje + 1 }}">
Fuerza Derecha <input sub="trasero" type="text" name="fuerza_derecha">
<br>
Resistencia Izquierda <input sub="frenos" type="text" name="resistencia_izquierda_{{ eje + 1 }}">
Eje Nº <input sub="trasero" type="text" name="eje">
<br>
Resistencia Derecha <input sub="frenos" type="text" name="resistencia_derecha_{{ eje + 1 }}">
<!--Peso Total--> <input hidden sub="trasero" type="text" name="peso_estatico">
<br>
Ovalidad Izquierda <input sub="frenos" type="text" name="ovalidad_izquierda_{{ eje + 1 }}">
<h1>Gases y Humos</h1>
Gases <input sub="gaseshumos" type="text" name="opacidad_logaritmica">
<br>
Ovalidad Derecha <input sub="frenos" type="text" name="ovalidad_derecha_{{ eje + 1 }}">
CO <input sub="gaseshumos" type="text" name="co">
<br>
Peso Total <input sub="frenos" type="text" name="peso_estatico_{{ eje + 1 }}">
HC <input sub="gaseshumos" type="text" name="hc">
<br>
<br>
{% endfor %}
<h1>Freno Trasero</h1>
Fuerza Izquierda <input sub="trasero" type="text" name="fuerza_izquierda">
<br>
Fuerza Derecha <input sub="trasero" type="text" name="fuerza_derecha">
<br>
Eje Nº <input sub="trasero" type="text" name="eje">
<br>
<!--Peso Total--> <input hidden sub="trasero" type="text" name="peso_estatico">
<br>
<h1>Gases y Humos</h1>
Gases <input sub="gaseshumos" type="text" name="opacidad_logaritmica">
<br>
CO <input sub="gaseshumos" type="text" name="co">
<br>
HC <input sub="gaseshumos" type="text" name="hc">
<br>
<br>
<br>
Por defecto: <input type="text" name="defecto" value="---">
<br>
<br>
Por defecto: <input type="text" name="defecto" value="---">
<br>
</div>
<div class="PDFButtonContainerFixed">
<button class="PDFButton" onclick=
......@@ -115,29 +117,33 @@
</button>
<img id="maha" src="{{ url_for('static', filename = 'assets/maha.png') }}" style="display: none;">
</div>
<div class="PDFButtonContainerFixed" style="bottom: 40%;">
<button class="PDFButton" style="bottom: 40%; display: {% if bypass %} none {% else %} block {% endif %};"
onclick="location.reload()">
Volver
</button>
</div>
</div>
<div id="form" style="height: 100%; display: {% if bypass %} none {% else %} block {% endif %}">
<div id="form" class="DataCard" style="height: auto; display: {% if bypass %} none {% else %} block {% endif %};">
<h1>Generación de PDF</h1>
Usuario <input required type="text" sub="credenciales" name="usuario">
<br>
Contraseña <input required type="password" sub="credenciales" name="contrasena">
<br>
Patente <input required type="text" sub="header" name="patente">
<br>
<h1>Datos de Suspensión</h1>
Rendimiento Izquierdo - Eje 1 <input required type="number" step="any" sub="suspension" name="rendimiento_izquierdo_1">
Rendimiento Izquierdo - Eje 1 <input type="number" step="any" sub="suspension" name="rendimiento_izquierdo_1">
<br>
Rendimiento Derecho - Eje 1 <input required type="number" step="any" sub="suspension" name="rendimiento_derecho_1">
Rendimiento Derecho - Eje 1 <input type="number" step="any" sub="suspension" name="rendimiento_derecho_1">
<br>
Rendimiento Izquierdo - Eje 2 <input required type="number" step="any" sub="suspension" name="rendimiento_izquierdo_2">
Rendimiento Izquierdo - Eje 2 <input type="number" step="any" sub="suspension" name="rendimiento_izquierdo_2">
<br>
Rendimiento Derecho - Eje 2 <input required type="number" step="any" sub="suspension" name="rendimiento_derecho_2">
Rendimiento Derecho - Eje 2 <input type="number" step="any" sub="suspension" name="rendimiento_derecho_2">
<br>
Por defecto: <input name="defecto" type="text" value="---">
<div class="PDFButtonContainer">
<button class="PDFButton" onclick="collectToSearch()">
Buscar
......
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script src="{{ url_for('static', filename = 'src/ajax.js') }}"></script>
<script src="{{ url_for('static', filename = 'src/forms.js') }}"></script>
<script src="{{ url_for('static', filename = 'src/login.js') }}"></script>
<link rel="stylesheet" href="{{ url_for('static', filename = 'styles/login.css') }}">
<!--INCLUIMOS LA FUENTE-->
<link rel="stylesheet" media="screen" href="https://fontlibrary.org/face/cmu-typewriter" type="text/css" />
<title>Login</title>
</head>
<body>
<div class="LoginCard">
<h2>Usuario:</h2>
<br>
<input required type="text" name="usuario" style="margin: auto;">
<br>
<br>
<h2>Contraseña:</h2>
<br>
<input required type="password" name="contrasena" style="margin: auto;">
<button class="PDFButton bottom" onclick="login()">
Entrar
</button>
</div>
<div id="message" class="MessageContainer" onclick="this.style.display = 'none'" style="display: none;">
<div class="Message" style="text-align: center;">
<p id="msg"></p>
<span class="X">x<span>
</div>
</div>
</body>
</html>
\ No newline at end of file
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!