{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Publicar una web gratis con GitHub Pages\n",
    "\n",
    "Un repositorio, un archivo y una dirección que puedes mandar por WhatsApp\n",
    "\n",
    "Cuaderno de soluciones del capítulo 19 de **Git desde cero**, de Miss Yera.\n",
    "\n",
    "Corre de arriba abajo. Si lo abres en Google Colab no necesitas instalar nada.\n",
    "\n",
    "Capítulo completo: https://missyera.com/guias/git-desde-cero/publicar-una-web/\n",
    "\n",
    "Este es el cuaderno de **soluciones**. Trae el código de cada ejercicio, la\n",
    "explicación de la trampa y la respuesta del quiz. Si vienes del cuaderno de\n",
    "práctica sin haberlo intentado, vuelve 🙂"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Antes de empezar\n",
    "\n",
    "Este capítulo son comandos de terminal, no Python. La celda de abajo baja el\n",
    "ayudante que los ejecuta y que **recuerda en qué carpeta quedaste**, que es lo\n",
    "que hace falta para que un `cd` de una celda siga valiendo en la siguiente.\n",
    "\n",
    "A partir de ahí, cada celda de comandos empieza por `%%consola`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import urllib.request\n",
    "\n",
    "# El ayudante de los cuadernos. Trae la corrección de los ejercicios y, en los\n",
    "# capítulos de consola, la celda mágica que ejecuta los comandos. Se baja en\n",
    "# vez de venir pegado aquí para que siempre sea el último.\n",
    "urllib.request.urlretrieve(\n",
    "    \"https://missyera.com/static/cuadernos/revisa.py\", \"revisa.py\")\n",
    "import revisa\n",
    "revisa.carga({}, lenguaje=\"bash\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Este es el capítulo que más gusta, porque es donde el repositorio deja de\n",
    "ser una carpeta y se convierte en algo que puedes mandar por WhatsApp 📲\n",
    "\n",
    "GitHub Pages es hospedaje gratis para páginas web. No hay servidor que\n",
    "contratar, no hay tarjeta, no hay panel de control. Hay un repositorio."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Qué se puede publicar y qué no"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "| Sí | No |\n",
    "|---|---|\n",
    "| HTML, CSS y JavaScript | Python, PHP o cualquier cosa de servidor |\n",
    "| Un portafolio, un reporte, una landing | Un formulario que guarde en base de datos |\n",
    "| Datos leídos de un CSV o un JSON del propio repositorio | Cualquier cosa con contraseñas dentro |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La regla corta: si tu página funciona abriendo el archivo con doble clic en\n",
    "tu computadora, funciona en Pages 🖱️"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## El archivo que hace falta"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Uno solo, y tiene que llamarse `index.html`. Vamos a hacer el\n",
    "reporte de ventas por ciudad:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "mkdir reporte-ventas\n",
    "cd reporte-ventas\n",
    "git init -q\n",
    "cat > index.html <<'FIN'\n",
    "<!doctype html>\n",
    "<html lang=\"es\">\n",
    "<head><meta charset=\"utf-8\"><title>Ventas por ciudad</title></head>\n",
    "<body>\n",
    "  <h1>Ventas por ciudad</h1>\n",
    "  <table>\n",
    "    <tr><th>Ciudad</th><th>Monto</th></tr>\n",
    "    <tr><td>Lima</td><td>1200</td></tr>\n",
    "    <tr><td>Arequipa</td><td>890</td></tr>\n",
    "  </table>\n",
    "</body>\n",
    "</html>\n",
    "FIN\n",
    "git add index.html\n",
    "git commit -q -m \"Primera version del reporte web de ventas\"\n",
    "ls\n",
    "head -4 index.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Eso es una página web completa. Se puede abrir con doble clic ahora mismo y\n",
    "se ve 🌐"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Publicarla"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Se sube como cualquier otro proyecto, con lo del capítulo\n",
    "17:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "cd ..\n",
    "git init -q --bare servidor.git\n",
    "cd reporte-ventas\n",
    "git remote add origin ../servidor.git\n",
    "git push -u origin main"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Y en GitHub se activa en *Settings > Pages*: en\n",
    "**Source** eliges *Deploy from a branch*, la rama\n",
    "`main` y la carpeta `/ (root)`. Guardas.\n",
    "\n",
    "Dos minutos después, la dirección aparece arriba de esa misma pantalla:\n",
    "`https://tuusuario.github.io/reporte-ventas/`. Esa es la que mandas\n",
    "por WhatsApp 🎉"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Los tres tropiezos del primer intento"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- **El archivo no se llama `index.html`.** Si se\n",
    "llama `reporte.html`, la dirección de arriba da 404 y hay que entrar\n",
    "a `.../reporte-ventas/reporte.html`.\n",
    "\n",
    "- **El repositorio es privado.** Con cuenta gratuita, Pages\n",
    "necesita repositorio público.\n",
    "\n",
    "- **Miraste a los diez segundos.** Tarda un par de minutos la\n",
    "primera vez, y a veces más."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "mv index.html reporte.html\n",
    "ls\n",
    "test -f index.html && echo \"hay index\" || echo \"sin index.html: la raiz dara 404\"\n",
    "mv reporte.html index.html\n",
    "test -f index.html && echo \"arreglado\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ojo con lo que va de paquete"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pages publica **todo el contenido de la rama**. Si en el\n",
    "repositorio hay un CSV con los clientes, ese CSV se descarga escribiendo su\n",
    "dirección, aunque ninguna página enlace a él."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "printf 'cliente,ciudad,monto\\nBodega Inti,Cusco,760\\n' > clientes.csv\n",
    "printf 'no publicar esto\\n' > notas-internas.md\n",
    "git add .\n",
    "git commit -q -m \"Entran datos que NO deberian publicarse\"\n",
    "git ls-files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Los tres archivos quedarían publicados. Lo que se hace es sacarlos del\n",
    "repositorio y dejarlos fuera con lo del capítulo\n",
    "9:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git rm -q --cached clientes.csv notas-internas.md\n",
    "printf 'clientes.csv\\nnotas-internas.md\\n' > .gitignore\n",
    "git add .gitignore\n",
    "git commit -q -m \"Los datos internos salen del repositorio\"\n",
    "git ls-files\n",
    "git status --short"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ahora el repositorio solo tiene lo publicable. Los archivos siguen en tu\n",
    "carpeta, pero ya no viajan 🧳"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### La trampa\n",
    "\n",
    "Publicas la web del reporte de ventas con GitHub Pages para enseñársela a tu jefe. La página se ve preciosa.\n",
    "\n",
    "```\n",
    "$ ls\n",
    "index.html  ventas.csv  clientes.csv  notas-internas.md\n",
    "\n",
    "$ git push origin main\n",
    "To github.com:tuusuario/reporte.git\n",
    "   3c1f80a..8a2b19c  main -> main\n",
    "```\n",
    "\n",
    "**Qué está mal**\n",
    "\n",
    "Pages publica **el repositorio entero**, no solo el HTML 🌐\n",
    "\n",
    "La página que se ve bonita es `index.html`, pero todo lo demás que esté en esa rama queda accesible por su dirección directa: `tuusuario.github.io/reporte/clientes.csv` se descarga sin pedir nada, y las notas internas también.\n",
    "\n",
    "Y hay una capa más: el repositorio de una Pages gratuita tiene que ser público, así que además los archivos están en el repositorio a la vista de cualquiera.\n",
    "\n",
    "La costumbre: lo que se publica va en su propia carpeta con solo lo publicable dentro, y lo que no se publica no entra al repositorio, que es de lo que trata el capítulo 9."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comprueba que se entendió"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Comprueba que lo tienes\n",
    "\n",
    "Activaste Pages y la dirección da 404. ¿Qué revisas primero?\n",
    "\n",
    "a) Que el archivo se llame `index.html` y esté en la raíz\n",
    "\n",
    "b) Que el HTML no tenga errores\n",
    "\n",
    "c) Que tenga un dominio propio configurado\n",
    "\n",
    "d) Que el repositorio tenga licencia\n",
    "\n",
    "---\n",
    "\n",
    "**La correcta es la a.**\n",
    "\n",
    "*b)* Un HTML con errores se ve mal, pero se ve. El 404 es que no encontró qué mostrar.\n",
    "\n",
    "*c)* El dominio propio es opcional. Sin él, la dirección de github.io funciona igual.\n",
    "\n",
    "*d)* La licencia no tiene nada que ver con que la página se publique.\n",
    "\n",
    "Sin `index.html` en la raíz, no hay portada que mostrar 🚪"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ejercicios"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1. Crea la página del catálogo\n",
    "\n",
    "Un `index.html` con la tabla de bodegas."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "cd ..\n",
    "mkdir catalogo-web\n",
    "cd catalogo-web\n",
    "git init -q\n",
    "cat > index.html <<'FIN'\n",
    "<!doctype html>\n",
    "<html lang=\"es\">\n",
    "<head><meta charset=\"utf-8\"><title>Catalogo de bodegas</title></head>\n",
    "<body><h1>Bodegas por ciudad</h1><p>Bodega Inti, Cusco</p></body>\n",
    "</html>\n",
    "FIN\n",
    "git add index.html\n",
    "git commit -q -m \"Pagina del catalogo de bodegas\"\n",
    "ls\n",
    "wc -l index.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "index.html\n",
    "5 index.html\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cinco líneas y ya es una web publicable."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2. Súbela\n",
    "\n",
    "Móntale el servidor y haz el primer push."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "cd ..\n",
    "git init -q --bare catalogo-servidor.git\n",
    "cd catalogo-web\n",
    "git remote add origin ../catalogo-servidor.git\n",
    "git push -u origin main"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "To ../catalogo-servidor.git\n",
    " * [new branch]      main -> main\n",
    "branch 'main' set up to track 'origin/main'.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Con GitHub, aquí es donde entras a Settings y activas Pages."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3. Comprueba el nombre del archivo\n",
    "\n",
    "Verifica que existe el `index.html` en la\n",
    "raíz."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "test -f index.html && echo \"listo para Pages\" || echo \"falta index.html\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "listo para Pages\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "El 90% de los 404 del primer intento son esto."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4. Agrega una segunda página\n",
    "\n",
    "Pages sirve cualquier archivo de la rama por su nombre."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "printf '<h1>Ventas por canal</h1><p>Bodegas 4200</p>\\n' > canales.html\n",
    "git add canales.html\n",
    "git commit -q -m \"Pagina de ventas por canal\"\n",
    "git push -q origin main\n",
    "git ls-files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "canales.html\n",
    "index.html\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Esa segunda vive en `.../catalogo-web/canales.html`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5. Mira qué se publicaría\n",
    "\n",
    "Lista todo lo que la rama llevaría a la web."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "printf 'cliente,monto\\nBodega Inti,760\\n' > clientes.csv\n",
    "git add clientes.csv\n",
    "git commit -q -m \"Entra el CSV de clientes\"\n",
    "git ls-files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "canales.html\n",
    "clientes.csv\n",
    "index.html\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Ese CSV se descargaría escribiendo su dirección. Nadie lo enlaza, y da\n",
    "igual 👀"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6. Sácalo de la publicación\n",
    "\n",
    "Quita el CSV del repositorio sin borrarlo de tu carpeta."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "git rm -q --cached clientes.csv\n",
    "printf 'clientes.csv\\n' > .gitignore\n",
    "git add .gitignore\n",
    "git commit -q -m \"El CSV de clientes sale de la web\"\n",
    "git ls-files\n",
    "ls"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    ".gitignore\n",
    "canales.html\n",
    "index.html\n",
    "canales.html\n",
    "clientes.csv\n",
    "index.html\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fuera del repositorio, dentro de tu carpeta. Es exactamente lo que\n",
    "quieres 🧹"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 7. Pide una página que no existe\n",
    "\n",
    "Comprueba en tu propia carpeta lo que Pages te contestaría\n",
    "con un 404."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%consola\n",
    "cat contacto.html"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```\n",
    "cat: contacto.html: No such file or directory\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lo mismo que pasa en la web: si el archivo no está en la rama, no hay página\n",
    "que mostrar 🕳️"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Lo que te llevas"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Un `index.html` en la raíz de un repositorio público y ya\n",
    "tienes web. Y todo lo demás de esa rama también se publica.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "Ese era el capítulo 19 de **Git desde cero**. El texto completo, con las salidas de cada bloque, está en https://missyera.com/guias/git-desde-cero/publicar-una-web/\n",
    "\n",
    "Que tengas lindo día! 🌸"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
