Convertir asistencia a csv, scripts auxiliares para facilitar la web
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
226021a203
commit
6915f7e0b4
22
README.md
22
README.md
|
@ -31,21 +31,31 @@ que hay apuntados para cenar el sábado.
|
||||||
|
|
||||||
## Crear contenido
|
## Crear contenido
|
||||||
|
|
||||||
Para crear un nodo que se llame `nodo1` para el 2019:
|
Hay una serie de comandos auxiliares para gestionar el contenido de la web de
|
||||||
|
manera sencilla.
|
||||||
|
|
||||||
hugo new 2019/nodos/nodo1.md -k nodo
|
Todos estos comandos aceptan un parámetro opcional: el año en el que estamos
|
||||||
|
trabajando. Si no se indica año se asume el actual.
|
||||||
|
|
||||||
Para apuntarse como asistente:
|
Para crear un nodo:
|
||||||
|
|
||||||
hugo new 2019/asistencia/persona.md -k asistencia
|
bin/nuevo_nodo
|
||||||
|
|
||||||
|
Para gestionar la asistencia:
|
||||||
|
|
||||||
|
bin/asistencia
|
||||||
|
|
||||||
|
Para gestionar las necesidades:
|
||||||
|
|
||||||
|
bin/necesidades
|
||||||
|
|
||||||
Para crear una página corriente:
|
Para crear una página corriente:
|
||||||
|
|
||||||
hugo new 2019/como-llegar.md
|
bin/nueva_pagina
|
||||||
|
|
||||||
Para empezar un nuevo hackmeeting:
|
Para empezar un nuevo hackmeeting:
|
||||||
|
|
||||||
hugo new 2022 -k hm
|
bin/nuevo_hackmeeting
|
||||||
|
|
||||||
|
|
||||||
## Mini intro a Hugo
|
## Mini intro a Hugo
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
---
|
|
||||||
title: "{{ replace .Name "-" " " | title }}"
|
|
||||||
date: {{ .Date }}
|
|
||||||
type: "asistencia"
|
|
||||||
entrada: "fecha"
|
|
||||||
salida: "fecha"
|
|
||||||
dieta: "omnivora"
|
|
||||||
camiseta: "talla(s)"
|
|
||||||
material: ["proyector", "internet"]
|
|
||||||
dormir: "si (notas)"
|
|
||||||
comer: "si (notas)"
|
|
||||||
necesidades: ""
|
|
||||||
draft: false
|
|
||||||
---
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
YEAR=${1:-$(date "+%Y")}
|
||||||
|
|
||||||
|
utils/csveditor.py content/${YEAR}/asistencia.csv
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
YEAR=${1:-$(date "+%Y")}
|
||||||
|
|
||||||
|
utils/csveditor.py content/${YEAR}/necesidades.csv
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
YEAR=${1:-$(date "+%Y")}
|
||||||
|
|
||||||
|
echo -n "Titulo: "
|
||||||
|
read TITLE
|
||||||
|
SLUG=$(bin/slugify ${TITLE})
|
||||||
|
|
||||||
|
hugo new ${YEAR}/${SLUG}.md
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
YEAR=${1:-$(date "+%Y")}
|
||||||
|
|
||||||
|
hugo new ${YEAR} -k hm
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
YEAR=${1:-$(date "+%Y")}
|
||||||
|
|
||||||
|
echo -n "Titulo: "
|
||||||
|
read TITLE
|
||||||
|
SLUG=$(bin/slugify ${TITLE})
|
||||||
|
|
||||||
|
hugo new ${YEAR}/nodos/${SLUG}.md -k nodo
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Versión simplificada y adaptada de bash-slugify
|
||||||
|
# https://github.com/brutus/bash-slugify
|
||||||
|
slugify () {
|
||||||
|
local name="$@"
|
||||||
|
local gluechars='-_. '
|
||||||
|
local safechars="${gluechars}a-zA-Z0-9"
|
||||||
|
|
||||||
|
# convert to lowercase
|
||||||
|
name=$(echo "${name}" | tr A-ZÄÖÜ a-zäöü)
|
||||||
|
|
||||||
|
# remove special chars
|
||||||
|
name=$(echo "${name//[^${safechars}]/}")
|
||||||
|
|
||||||
|
# consolidate spaces
|
||||||
|
name=$(echo "${name}" | tr -s '[:space:]')
|
||||||
|
|
||||||
|
# replace spaces with dashes
|
||||||
|
name=$(echo "${name}" | tr ' ' '-')
|
||||||
|
|
||||||
|
# remove spaces around dashes and underscores
|
||||||
|
name=$(echo "${name// -/-}")
|
||||||
|
name=$(echo "${name//- /-}")
|
||||||
|
name=$(echo "${name// _/_}")
|
||||||
|
name=$(echo "${name//_ /_}")
|
||||||
|
|
||||||
|
# trim spaces
|
||||||
|
name=$(echo "${name}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
|
||||||
|
|
||||||
|
# replace special chars
|
||||||
|
name=$(echo "${name//[^${safechars}]/$REPLACEMENT_CHAR}")
|
||||||
|
|
||||||
|
## REPLACE SPACES
|
||||||
|
name=$(echo "${name// /$SPACE_CHAR}")
|
||||||
|
|
||||||
|
# return slug
|
||||||
|
echo "${name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $(slugify "$@")
|
|
@ -0,0 +1,2 @@
|
||||||
|
"Nombre","Entrada","Salida","Dieta","Camiseta","Material","Dormir","Comer","Necesidades"
|
||||||
|
"Shagi","2019-09-19","2010-09-22","omnivora","L","","sí (en furgo)","sí",""
|
|
|
@ -1,10 +1,11 @@
|
||||||
---
|
---
|
||||||
title: "Asistencia"
|
title: "Asistencia"
|
||||||
date: 2021-09-14T11:29:27+02:00
|
date: 2021-09-14T11:29:27+02:00
|
||||||
type: "asistencia"
|
|
||||||
draft: false
|
draft: false
|
||||||
---
|
---
|
||||||
|
|
||||||
Esta es la plantilla para inscribirse y que sepamos de antemano cuanta gente va
|
Esta es la plantilla para inscribirse y que sepamos de antemano cuanta gente va
|
||||||
a venir, para poder preparar el espacio y lo que haga falta. Avisa en matrix o
|
a venir, para poder preparar el espacio y lo que haga falta. Avisa en matrix o
|
||||||
en la lista, o envía un pull request con al repositorio de esta web.
|
en la lista, o envía un pull request al repositorio de esta web.
|
||||||
|
|
||||||
|
{{< csvTable file="/content/2019/asistencia.csv" class="asistencia" >}}
|
|
@ -1,14 +0,0 @@
|
||||||
---
|
|
||||||
title: "Shagi"
|
|
||||||
date: 2021-09-17T11:42:10+02:00
|
|
||||||
type: "asistencia"
|
|
||||||
entrada: "2019-09-19"
|
|
||||||
salida: "2010-09-22"
|
|
||||||
dieta: "omnivora"
|
|
||||||
camiseta: "L"
|
|
||||||
material:
|
|
||||||
dormir: "sí (en furgo)"
|
|
||||||
comer: "sí"
|
|
||||||
necesidades: ""
|
|
||||||
draft: false
|
|
||||||
---
|
|
|
@ -1,42 +0,0 @@
|
||||||
{{ define "main" }}
|
|
||||||
{{ .Content }}
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Quién</th>
|
|
||||||
<th>Entrada</th>
|
|
||||||
<th>Salida</th>
|
|
||||||
<th>Tipo de comida</th>
|
|
||||||
<th>Talla camiseta</th>
|
|
||||||
<th>Material/Otros</th>
|
|
||||||
<th>Dormir</th>
|
|
||||||
<th>Comer</th>
|
|
||||||
<th>Necesidades Especiales</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{ range where .Pages "Params.type" "asistencia" }}
|
|
||||||
<tr>
|
|
||||||
<td>{{ .Title }}</td>
|
|
||||||
<td>{{ .Params.entrada }}</td>
|
|
||||||
<td>{{ .Params.salida }}</td>
|
|
||||||
<td>{{ .Params.dieta }}</td>
|
|
||||||
<td>{{ .Params.camiseta }}</td>
|
|
||||||
<td>{{ .Params.material }}</td>
|
|
||||||
<td>{{ .Params.dormir }}</td>
|
|
||||||
<td>{{ .Params.comer }}</td>
|
|
||||||
<td>{{ .Params.necesidades }}</td>
|
|
||||||
</tr>
|
|
||||||
{{ end }}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "sidebar_menu" }}
|
|
||||||
<ul>
|
|
||||||
{{ range .Parent.Pages }}
|
|
||||||
<li><a href="{{ .Permalink }}">{{.Title}}</a></li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ end}}
|
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
import atexit
|
||||||
|
import csv
|
||||||
|
import os
|
||||||
|
import readline
|
||||||
|
import sys
|
||||||
|
from cmd import Cmd
|
||||||
|
|
||||||
|
def init_readline():
|
||||||
|
histfile = os.path.join(os.path.expanduser("~"), ".hmwebot_history")
|
||||||
|
|
||||||
|
try:
|
||||||
|
readline.read_history_file(histfile)
|
||||||
|
h_len = readline.get_current_history_length()
|
||||||
|
except FileNotFoundError:
|
||||||
|
open(histfile, 'wb').close()
|
||||||
|
h_len = 0
|
||||||
|
|
||||||
|
def save(prev_h_len, histfile):
|
||||||
|
new_h_len = readline.get_current_history_length()
|
||||||
|
readline.set_history_length(1000)
|
||||||
|
readline.append_history_file(new_h_len - prev_h_len, histfile)
|
||||||
|
atexit.register(save, h_len, histfile)
|
||||||
|
|
||||||
|
|
||||||
|
def rlinput(prompt, prefill=''):
|
||||||
|
readline.set_startup_hook(lambda: readline.insert_text(prefill))
|
||||||
|
try:
|
||||||
|
return input(prompt) # or raw_input in Python 2
|
||||||
|
finally:
|
||||||
|
readline.set_startup_hook()
|
||||||
|
|
||||||
|
|
||||||
|
class CSVEditor:
|
||||||
|
def __init__(self, filename):
|
||||||
|
self.filename = filename
|
||||||
|
with open(filename, 'r') as f:
|
||||||
|
reader = csv.DictReader(f)
|
||||||
|
self.fieldnames = reader.fieldnames
|
||||||
|
self.data = [data for data in reader]
|
||||||
|
|
||||||
|
def get_list(self, title_field):
|
||||||
|
return [(idx, data[title_field]) for idx, data in enumerate(self.data)]
|
||||||
|
|
||||||
|
def get(self, idx):
|
||||||
|
try:
|
||||||
|
return self.data[idx]
|
||||||
|
except IndexError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def show(self, idx):
|
||||||
|
line = self.get(idx)
|
||||||
|
if line is None:
|
||||||
|
return "Índice fuera de rango"
|
||||||
|
output = [
|
||||||
|
f"{field}: {value}"
|
||||||
|
for field, value in line.items()
|
||||||
|
]
|
||||||
|
return "\n".join(output)
|
||||||
|
|
||||||
|
def edit(self, idx, item):
|
||||||
|
self.data[idx] = item
|
||||||
|
|
||||||
|
def delete(self, idx):
|
||||||
|
if idx in self.data:
|
||||||
|
del self.data[idx]
|
||||||
|
|
||||||
|
def _edit(self, item):
|
||||||
|
editing = True
|
||||||
|
while editing:
|
||||||
|
for fieldname in self.fieldnames:
|
||||||
|
item[fieldname] = rlinput(f"{fieldname}: ", prefill=item.get(fieldname, ''))
|
||||||
|
|
||||||
|
editing = rlinput('Terminado (s/N)?').lower() == 'n'
|
||||||
|
|
||||||
|
def edit(self, idx):
|
||||||
|
item = self.get(idx)
|
||||||
|
if item is None:
|
||||||
|
return
|
||||||
|
self._edit(item)
|
||||||
|
self.data[idx] = item
|
||||||
|
|
||||||
|
def add(self):
|
||||||
|
item = {}
|
||||||
|
self._edit(item)
|
||||||
|
self.data.append(item)
|
||||||
|
|
||||||
|
def write(self):
|
||||||
|
with open(self.filename, 'w') as f:
|
||||||
|
writer = csv.DictWriter(f, fieldnames=self.fieldnames)
|
||||||
|
writer.writeheader()
|
||||||
|
writer.writerows(self.data)
|
||||||
|
|
||||||
|
|
||||||
|
class CSVEditorCmd(Cmd):
|
||||||
|
"Editor interactivo de ficheros csv"
|
||||||
|
|
||||||
|
def __init__(self, filename, title_field=None):
|
||||||
|
super().__init__()
|
||||||
|
self.csveditor = CSVEditor(filename)
|
||||||
|
self.title_field = title_field
|
||||||
|
if title_field is None:
|
||||||
|
self.title_field = self.csveditor.fieldnames[0]
|
||||||
|
self.do_help('')
|
||||||
|
|
||||||
|
def do_list(self, arg):
|
||||||
|
"Listar el contenido del csv"
|
||||||
|
for idx, item in self.csveditor.get_list(self.title_field):
|
||||||
|
print(f"{idx}) {item}")
|
||||||
|
|
||||||
|
def do_show(self, arg):
|
||||||
|
"Mostrar la línea con el índice indicado"
|
||||||
|
try:
|
||||||
|
idx = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print("Tienes que indicar un número")
|
||||||
|
return
|
||||||
|
print(self.csveditor.show(idx))
|
||||||
|
|
||||||
|
def do_add(self, arg):
|
||||||
|
"Añadir una nueva entrada"
|
||||||
|
self.csveditor.add()
|
||||||
|
|
||||||
|
def do_edit(self, arg):
|
||||||
|
"Editar la entrada con el índice indicado"
|
||||||
|
try:
|
||||||
|
idx = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print("Tienes que indicar un número")
|
||||||
|
return
|
||||||
|
self.csveditor.edit(idx)
|
||||||
|
|
||||||
|
def do_delete(self, arg):
|
||||||
|
"Quitar la entrada con el índice indicado"
|
||||||
|
try:
|
||||||
|
idx = int(arg)
|
||||||
|
except ValueError:
|
||||||
|
print("Tienes que indicar un número")
|
||||||
|
return
|
||||||
|
self.csveditor.delete(idx)
|
||||||
|
|
||||||
|
def do_save(self, arg):
|
||||||
|
"Guardar la lista actualizada"
|
||||||
|
self.csveditor.write()
|
||||||
|
|
||||||
|
def do_quit(self, arg):
|
||||||
|
"Terminar"
|
||||||
|
return True
|
||||||
|
|
||||||
|
do_EOF = do_quit
|
||||||
|
|
||||||
|
|
||||||
|
parser = ArgumentParser(
|
||||||
|
description='Editor sencillo de ficheros CSV')
|
||||||
|
|
||||||
|
parser.add_argument('csvfile', help='Fichero que hay que editar.')
|
||||||
|
parser.add_argument('-t', '--title', help='Columna principal del CSV, por defecto la primera.')
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
init_readline()
|
||||||
|
# bot = Bot()
|
||||||
|
args = parser.parse_args()
|
||||||
|
cmd = CSVEditorCmd(args.csvfile, args.title)
|
||||||
|
cmd.cmdloop()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,15 @@
|
||||||
|
Tareas que hay que facilitar:
|
||||||
|
|
||||||
|
- nuevo nodo
|
||||||
|
- nueva asistencia
|
||||||
|
igual cambiar el sistema actual para que sea también un csv, así podemos
|
||||||
|
cambiar las columnas necesarias para cada año
|
||||||
|
|
||||||
|
el programa pregunta y añade, o busca en la lista para quitar a alguien
|
||||||
|
- necesidades
|
||||||
|
poder pedir proyectores, material de limpieza, gente, etc.
|
||||||
|
|
||||||
|
un csv con tres columnas: texto, cantidad necesaria, cantidad actual
|
||||||
|
|
||||||
|
el programa pregunta por una de las líneas del csv para borrar, editar, cambiar la cantidad,
|
||||||
|
también se pueden añadir nuevas líneas
|
Loading…
Reference in New Issue