Compare commits

...

10 Commits

Author SHA1 Message Date
ef3c1f4bfe Fixed deploys 2021-11-27 13:28:39 +01:00
Marce Coll
f04bb3f69b Merge branch 'main' of ssh://git.lajuntament.space:2222/lajuntament/absencia-de-presencia 2021-11-27 13:26:01 +01:00
Marce Coll
139e11b5fc Some style, fixed JS 2021-11-27 13:25:20 +01:00
ad26ef0196 Calia uwsgi! 2021-11-27 13:10:46 +01:00
5729cbe18a Fitxers de deploy 2021-11-27 13:09:11 +01:00
Marce Coll
7a8ae86a1c Habemus frontend 2021-11-27 13:05:12 +01:00
Marce Coll
603e6dba2b Merge branch 'main' of ssh://git.lajuntament.space:2222/lajuntament/absencia-de-presencia 2021-11-27 12:43:05 +01:00
Marce Coll
8449700e68 Static 2021-11-27 12:41:54 +01:00
1c2ee7238a Merge branch 'main' of ssh://git.lajuntament.space:2222/lajuntament/absencia-de-presencia 2021-11-27 12:39:32 +01:00
08f7847419 Afegit endpoint de calcular presència. 2021-11-27 12:36:44 +01:00
9 changed files with 163 additions and 7 deletions

14
deploy/Dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM python:3.8
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY main.py .
COPY static static
COPY templates templates
COPY deploy/presencia.ini .
CMD ["uwsgi", "--ini", "presencia.ini"]

10
deploy/presencia.ini Normal file
View File

@@ -0,0 +1,10 @@
[uwsgi]
module = main:app
chown = www-data:www-data
uid = www-data
gid = www-data
chdir = /app/
processes = 4
threads = 2
http = 0.0.0.0:5000
wsgi-disable-file-wrapper = false

9
deploy/publish.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
set -e
# BUILD
docker build . -f deploy/Dockerfile -t presencia
# PUBLISH
docker tag presencia marc.sastre.cat/presencia
docker push marc.sastre.cat/presencia

11
index.html Normal file
View File

@@ -0,0 +1,11 @@
<html>
<head>
<title>Absencia de Presencia</title>
</head>
<body>
<form>
<input type="text"/>
<input type="submit"/>
</form>
</body>
</html>

43
main.py
View File

@@ -1,11 +1,10 @@
import functools import functools
import io import re
import flask import flask
from werkzeug.wsgi import FileWrapper text2bool = {"absència": True, "absencia": True, "presencia": False, "presència": False, "absent": True, "present": False}
bool2text = {True: "absent", False: "present"}
import dibuixa
app = flask.Flask(__name__) app = flask.Flask(__name__)
@@ -23,16 +22,46 @@ def handle_errors(func):
return func(*args, **kwargs) return func(*args, **kwargs)
except HTTPError as r: except HTTPError as r:
return r, r.status_code return r, r.status_code
except Exception: except Exception as e:
print(e)
return flask.Response("Oh no! Hi ha hagut un error en el servidor :(", status="Internal error"), 500 return flask.Response("Oh no! Hi ha hagut un error en el servidor :(", status="Internal error"), 500
return wrapped return wrapped
@app.route("/") @app.route("/")
def index():
return flask.render_template("./index.html")
@app.route("/calcula", methods=['POST'])
@handle_errors @handle_errors
def hola(code): def calcula():
return "Hola" frase = flask.request.get_json().get('frase')
if not frase:
raise HTTPError("Cal introduir una frase!", status_code=400, status="Missing parameter")
return calcula_presencia(frase)
@app.route("/static/<path:path>")
def static_files(path):
return flask.send_from_directory('static', path)
def xor(a, b):
return (a and not b) or (b and not a)
def calcula_presencia(frase):
frase = frase[3:]
subjecte, atribut = frase.split(" és ")
llista_subjecte = re.split(" de | d'", subjecte)
objecte = llista_subjecte[-1]
llista_bool = [text2bool[x.strip()] for x in llista_subjecte[:-1]]
bool_total = text2bool[atribut]
for bool in llista_bool:
bool_total = xor(bool_total, bool)
return f'{objecte} és {bool2text[bool_total]}'
if __name__ == "__main__": if __name__ == "__main__":

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
Flask==2.0.2
uwsgi==2.0.19.1

38
static/index.js Normal file
View File

@@ -0,0 +1,38 @@
const r = (callback) => window.addEventListener('DOMContentLoaded', callback);
const g = (name) => document.getElementById(name);
r(() => {
g('submit').addEventListener('click', async () => {
const frase = g('frase').value;
const response = await fetch('/calcula', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
'frase': frase
})
})
const resultat = await response.text();
g('response').innerHTML = resultat;
});
const afegirPart = (t) => {
const frase = g('frase');
let conector = ' de ';
if (frase.value === '') {
conector = 'la ';
}
g('frase').value = g('frase').value + conector + t;
}
g('absencia').addEventListener('click', () => {
afegirPart('absencia')
});
g('presencia').addEventListener('click', () => {
afegirPart('presencia')
});
})

23
static/style.css Normal file
View File

@@ -0,0 +1,23 @@
button {
padding: 30px;
font-size: 14px;
}
#frase {
width: 800px;
height: 300px;
text-align: center;
font-size: 17px;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
#buttons {
padding: 50px;
}

20
templates/index.html Normal file
View File

@@ -0,0 +1,20 @@
<html>
<head>
<title>Absencia de Presencia</title>
<script src="/static/index.js"></script>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div id="container">
<textarea id="frase"></textarea>
<div id="buttons">
<button id="absencia">Absencia</button>
<button id="presencia">Presencia</button>
<button id="submit">Calcula</button>
</div>
</div>
<p id="response"></p>
</body>
</html>