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
|
||||
|
||||
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:
|
||||
|
||||
hugo new 2019/como-llegar.md
|
||||
bin/nueva_pagina
|
||||
|
||||
Para empezar un nuevo hackmeeting:
|
||||
|
||||
hugo new 2022 -k hm
|
||||
bin/nuevo_hackmeeting
|
||||
|
||||
|
||||
## 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"
|
||||
date: 2021-09-14T11:29:27+02:00
|
||||
type: "asistencia"
|
||||
draft: false
|
||||
---
|
||||
|
||||
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
|
||||
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