Quitar el reparto por paquetes, que sobra al ir los países en el repositorio
Los zips por país y el descargador se hicieron para no meter 40 MB de visores en git. Como al final entran, esa vía no aporta nada y sí puede estorbar: descargar.py descomprimía encima de out/<país>/ y habría pisado en silencio un visor versionado con la copia de una release vieja. Fuera src/empaquetar.py, src/descargar.py y sus objetivos del Makefile. Se queda 'make selector', que sí hace falta: cada visor congela la lista de países al construirse y al calcular uno nuevo hay que rehacer el de los demás.
This commit is contained in:
parent
d817c66dec
commit
9f7e9dd173
6 changed files with 16 additions and 189 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -31,9 +31,6 @@ out/*/*
|
||||||
!out/*/candidatos_estrellas.csv
|
!out/*/candidatos_estrellas.csv
|
||||||
!out/*/stats.json
|
!out/*/stats.json
|
||||||
|
|
||||||
# Paquetes por país listos para subir a una release
|
|
||||||
dist/
|
|
||||||
|
|
||||||
# Restos de trabajo
|
# Restos de trabajo
|
||||||
*.log
|
*.log
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
15
Makefile
15
Makefile
|
|
@ -2,7 +2,7 @@
|
||||||
# así que se puede reejecutar solo la parte que interese.
|
# así que se puede reejecutar solo la parte que interese.
|
||||||
PY := ./.venv/bin/python
|
PY := ./.venv/bin/python
|
||||||
|
|
||||||
.PHONY: all datos rasters modelo salidas cobertura revisar empaquetar descargar selector limpio
|
.PHONY: all datos rasters modelo salidas cobertura revisar selector limpio
|
||||||
|
|
||||||
all: datos rasters modelo salidas revisar
|
all: datos rasters modelo salidas revisar
|
||||||
|
|
||||||
|
|
@ -52,16 +52,9 @@ cobertura:
|
||||||
revisar:
|
revisar:
|
||||||
$(PY) src/revisar.py
|
$(PY) src/revisar.py
|
||||||
|
|
||||||
## --- países: paquetes para publicar y descarga de los publicados ---
|
## --- desplegable de país ---
|
||||||
# El repositorio lleva España. Los demás se calculan (REGION=xx make all) o se
|
# Cada visor congela la lista de países al construirse, así que al calcular uno
|
||||||
# bajan ya hechos, que son unos pocos MB en vez de un par de horas.
|
# nuevo hay que rehacer el selector de los demás.
|
||||||
empaquetar:
|
|
||||||
$(PY) src/empaquetar.py
|
|
||||||
|
|
||||||
descargar:
|
|
||||||
$(PY) src/descargar.py $(or $(PAIS),todos)
|
|
||||||
|
|
||||||
# Vuelve a poner al día el desplegable de país de todos los visores en disco.
|
|
||||||
selector:
|
selector:
|
||||||
$(PY) src/paises.py
|
$(PY) src/paises.py
|
||||||
|
|
||||||
|
|
|
||||||
16
README.md
16
README.md
|
|
@ -34,7 +34,7 @@ No hace falta servidor ni conexión. Ojo: `visor.html` necesita la carpeta
|
||||||
| `out/ortho/` | Ortofoto PNOA de cada localización, 640 m de lado |
|
| `out/ortho/` | Ortofoto PNOA de cada localización, 640 m de lado |
|
||||||
| `out/stats.json` | Cifras del modelo, que leen el informe y el visor |
|
| `out/stats.json` | Cifras del modelo, que leen el informe y el visor |
|
||||||
| `src/` | El pipeline entero, reproducible |
|
| `src/` | El pipeline entero, reproducible |
|
||||||
| `out/<país>/` | Lo mismo para cada país calculado. No van al repositorio: se publican como paquetes (`make empaquetar`) y se bajan con `make descargar` |
|
| `out/<país>/` | El visor y los datos de cada uno de los otros 22 países |
|
||||||
|
|
||||||
## Cómo se calcula
|
## Cómo se calcula
|
||||||
|
|
||||||
|
|
@ -133,18 +133,10 @@ clima, así que ese 8 % del modelo deja de distinguir y les baja la banda de
|
||||||
estrellas a todos por igual. Finlandia no sale con cero cinco-estrellas porque
|
estrellas a todos por igual. Finlandia no sale con cero cinco-estrellas porque
|
||||||
sus sitios sean peores.
|
sus sitios sean peores.
|
||||||
|
|
||||||
## Bajarse un país, o calcular otro
|
## Calcular un país
|
||||||
|
|
||||||
El repositorio lleva España. Los demás se bajan ya hechos, que son unos pocos MB
|
Los 27 del catálogo ya están calculados y vienen en el repositorio. Para añadir
|
||||||
y un momento, en vez de un par de horas y 25 GB:
|
uno nuevo:
|
||||||
|
|
||||||
```bash
|
|
||||||
make descargar PAIS=is # solo Islandia
|
|
||||||
make descargar # todos los publicados
|
|
||||||
```
|
|
||||||
|
|
||||||
Aparecen en el desplegable de país del visor automáticamente. Y para calcular
|
|
||||||
uno que no esté:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./.venv/bin/python src/regions.py # ver el catálogo
|
./.venv/bin/python src/regions.py # ver el catálogo
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,16 @@
|
||||||
# Publicar
|
# Publicar
|
||||||
|
|
||||||
## Los países, fuera del repositorio
|
## Los países van dentro del repositorio
|
||||||
|
|
||||||
En el repositorio va **España y nada más**. Cada visor lleva el relieve y un
|
De cada país entra el visor —que es autónomo, lleva el relieve y el terreno
|
||||||
recorte de terreno por candidato incrustados en base64, así que pesa entre 1 y
|
incrustados— y los datos en CSV: unos 40 MB los 23. Fuera se quedan los WebP,
|
||||||
4 MB y cualquier recálculo reescribe el fichero entero: doce países en el
|
que van ya dentro del visor, los PNG de los mapas, que solo usa el informe, y
|
||||||
historial de git son cientos de MB en unos pocos recálculos, y el clon deja de
|
el GeoTIFF del score.
|
||||||
ser algo que la gente pueda bajarse sin pensárselo.
|
|
||||||
|
|
||||||
Los demás se publican como adjuntos de una release:
|
Al clonar están todos, y se salta de uno a otro desde el desplegable del visor.
|
||||||
|
|
||||||
```bash
|
Ojo al regenerar: el visor es binario a efectos de git, así que cada recálculo
|
||||||
make empaquetar # deja dist/rave-scout-<país>.zip, 13 MB los once
|
mete una copia entera en el historial y esa ya no sale.
|
||||||
```
|
|
||||||
|
|
||||||
Se suben a una release con la etiqueta `paises`. A partir de ahí, cualquiera:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make descargar PAIS=is
|
|
||||||
make descargar # todos los publicados
|
|
||||||
```
|
|
||||||
|
|
||||||
El paquete lleva el visor y los CSV, que es lo que hace falta para mirar el
|
|
||||||
país. Fuera se quedan los PNG de los mapas (solo los usa el informe, que
|
|
||||||
únicamente existe para España), los WebP (ya van dentro del visor) y el GeoTIFF
|
|
||||||
del score. Al descomprimir se actualiza solo el desplegable de país de todos los
|
|
||||||
visores que haya en disco, que si no el recién bajado no aparecería en los otros.
|
|
||||||
|
|
||||||
Si lo publicas en otro sitio, `RAVE_SCOUT_PAISES` manda sobre la dirección por
|
|
||||||
defecto:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
RAVE_SCOUT_PAISES=https://mi-servidor/rave-scout make descargar PAIS=no
|
|
||||||
```
|
|
||||||
|
|
||||||
## Este repositorio está en Gitea
|
## Este repositorio está en Gitea
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
"""Baja el visor de un país ya calculado, sin recalcular nada.
|
|
||||||
|
|
||||||
Calcular un país son un par de horas, varios GB de descarga y unos 25 GB de
|
|
||||||
disco. Quien solo quiera mirarlo no tiene por qué pagar eso: el visor es un
|
|
||||||
HTML autónomo de unos pocos MB.
|
|
||||||
|
|
||||||
python src/descargar.py is ie hr # países sueltos
|
|
||||||
python src/descargar.py todos # los que haya publicados
|
|
||||||
|
|
||||||
La dirección sale de RAVE_SCOUT_PAISES si está puesta, y si no de las releases
|
|
||||||
del repositorio. Si el paquete no está publicado todavía, lo dice y sigue con
|
|
||||||
el siguiente en vez de dejarlo a medias.
|
|
||||||
"""
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import urllib.error
|
|
||||||
import urllib.request
|
|
||||||
import zipfile
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
||||||
import paises
|
|
||||||
import regions as R
|
|
||||||
|
|
||||||
BASE = os.environ.get(
|
|
||||||
"RAVE_SCOUT_PAISES",
|
|
||||||
"https://gitea.laenre.net/hacklab/EXPLORER/releases/download/paises")
|
|
||||||
|
|
||||||
|
|
||||||
def bajar(code):
|
|
||||||
if code not in R.REGIONS:
|
|
||||||
print(f" {code}: no está en el catálogo (src/regions.py)")
|
|
||||||
return False
|
|
||||||
if code == R.DEFAULT:
|
|
||||||
print(f" {code}: es el país por defecto, ya viene en el repositorio")
|
|
||||||
return False
|
|
||||||
|
|
||||||
url = f"{BASE}/rave-scout-{code}.zip"
|
|
||||||
print(f" {R.REGIONS[code]['name']:14s} {url}")
|
|
||||||
try:
|
|
||||||
with urllib.request.urlopen(url, timeout=120) as r:
|
|
||||||
datos = r.read()
|
|
||||||
except urllib.error.HTTPError as e:
|
|
||||||
print(f" no está publicado todavía (HTTP {e.code})")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f" no se ha podido bajar: {type(e).__name__}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
with zipfile.ZipFile(io.BytesIO(datos)) as zf:
|
|
||||||
# Las rutas del zip son out/<país>/…, relativas a la raíz. Se comprueba
|
|
||||||
# que ninguna se salga de ahí antes de escribir nada: un zip es un
|
|
||||||
# fichero de fuera y '../' dentro de un nombre escribe donde quiera.
|
|
||||||
for nombre in zf.namelist():
|
|
||||||
destino = (paises.ROOT / nombre).resolve()
|
|
||||||
if not str(destino).startswith(str((paises.ROOT / "out").resolve())):
|
|
||||||
raise SystemExit(f" ruta sospechosa en el zip: {nombre}")
|
|
||||||
zf.extractall(paises.ROOT)
|
|
||||||
n = len(list(zf.namelist()))
|
|
||||||
print(f" {n} ficheros en out/{code}/")
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def main(args):
|
|
||||||
if not args:
|
|
||||||
raise SystemExit(__doc__)
|
|
||||||
if args == ["todos"]:
|
|
||||||
args = [c for c in R.REGIONS if c != R.DEFAULT]
|
|
||||||
|
|
||||||
ok = sum(bajar(c) for c in args)
|
|
||||||
if ok:
|
|
||||||
# Los visores llevan la lista de países congelada de cuando se
|
|
||||||
# construyeron: sin esto, el país recién bajado no sale en el
|
|
||||||
# desplegable de los demás.
|
|
||||||
print("\nactualizando el selector de país de los visores…")
|
|
||||||
paises.refrescar()
|
|
||||||
print(f"\n{ok} países añadidos.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main(sys.argv[1:])
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
"""Empaqueta cada país calculado en un zip para subirlo a una release.
|
|
||||||
|
|
||||||
El repositorio se queda con España. Los demás países pesan entre 1 y 4 MB de
|
|
||||||
visor cada uno, y como el visor lleva el relieve incrustado, cualquier recálculo
|
|
||||||
reescribe el fichero entero: en el historial de git eso son cientos de MB en
|
|
||||||
unos pocos recálculos, y el clon deja de ser portable.
|
|
||||||
|
|
||||||
Al paquete va solo lo que hace falta para mirar el país, que es el visor —es
|
|
||||||
autónomo, sin servidor ni conexión— y los datos en CSV. Fuera se quedan los
|
|
||||||
PNG de los mapas (solo los usa el informe, que únicamente existe para España),
|
|
||||||
los WebP (van ya incrustados dentro del visor) y el GeoTIFF del score, que pesa
|
|
||||||
lo que pesa y se regenera.
|
|
||||||
"""
|
|
||||||
import sys
|
|
||||||
import zipfile
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
|
||||||
import paises
|
|
||||||
import regions as R
|
|
||||||
|
|
||||||
DENTRO = ("visor.html", "candidatos_estrellas.csv", "stats.json")
|
|
||||||
DIST = paises.ROOT / "dist"
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
DIST.mkdir(exist_ok=True)
|
|
||||||
hechos = [(c, d, n) for c, d, n in paises.calculados() if c != R.DEFAULT]
|
|
||||||
if not hechos:
|
|
||||||
raise SystemExit("no hay ningún país calculado aparte del de por defecto")
|
|
||||||
|
|
||||||
total = 0
|
|
||||||
for code, d, n in sorted(hechos):
|
|
||||||
z = DIST / f"rave-scout-{code}.zip"
|
|
||||||
with zipfile.ZipFile(z, "w", zipfile.ZIP_DEFLATED, compresslevel=9) as zf:
|
|
||||||
for nombre in DENTRO:
|
|
||||||
f = d / nombre
|
|
||||||
if f.exists():
|
|
||||||
# Dentro del zip cuelgan de out/<país>/, para que se
|
|
||||||
# descomprima en su sitio desde la raíz del proyecto.
|
|
||||||
zf.write(f, f"out/{code}/{nombre}")
|
|
||||||
total += z.stat().st_size
|
|
||||||
print(f" {R.REGIONS[code]['name']:14s} {n:>4} localizaciones "
|
|
||||||
f"{z.stat().st_size/1e6:5.1f} MB {z.name}")
|
|
||||||
|
|
||||||
print(f"\n{len(hechos)} paquetes, {total/1e6:.1f} MB en {DIST}")
|
|
||||||
print("Súbelos como adjuntos de una release con la etiqueta 'paises'.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue