Este repositorio contiene el código solución al desafío número 4 Black and White del módulo Desarrollo de aplicaciones web con Node y Express de la beca Desarrollo de aplicaciones Full Stack Javascript Trainee dictada por Desafío Latam.
Los requisitos del proyecto son los siguientes:
Tecnologías Utilizadas |
---|
Express |
Express-handlebars |
Bootstrap |
JQuery |
Jimp |
UUID |
1.El servidor debe disponibilizar una ruta raíz que devuelva un HTML con el formulario para el ingreso de la URL de la imagen a tratar. (3 Puntos)
La ruta que disponibiliza la vista llamada inicio que contiene el formulario para ingresar la URL de una página la he creado usando el siguiente código:
router.get("/", (req, res) => {
res.render("inicio");
});
La vista inicio contiene el siguiente código handlebars:
2.Los estilos de este HTML deben ser definidos por un archivo CSS alojado en el servidor. (2 Puntos)
Estilizo la vista anterior usando bootstrap y un archivo css creado en la carpeta public las cuales disponibilizo del lado del cliente a partir del siguiente código:
router.use("/public", express.static(path.join(__dirname, "..", "public")));
router.use(
"/bootstrap_css",
express.static(
path.join(__dirname, "..", "node_modules", "bootstrap", "dist", "css"),
),
);
3.El formulario debe redirigir a otra ruta del servidor que deberá procesar la imagen tomada por la URL enviada del formulario con el paquete Jimp. La imagen debe ser procesada en escala de grises y redimensionada a unos 350px de ancho. (3 Puntos)
La otra ruta del servidor que maneja la data enviada del formulario es la siguiente:
router.get("/procesa_imagen", procesaImagen);
Para lo cual utilizo la función procesaImagen siguiente:
async function procesaImagen(req, res) {
const { imagen: imagenURL } = req.query;
if (validarURL(imagenURL)) {
try {
const imagenJimp = await Jimp.read(imagenURL);
const nombreImagen = `img${generarID()}.jpg`;
const rutaImagenServer = path.join(
__dirname,
"..",
"images",
nombreImagen,
);
const objeto = await imagenJimp
.resize(350, Jimp.AUTO)
.grayscale()
.writeAsync(rutaImagenServer);
res.status(200).json({ imagen: nombreImagen });
} catch (err) {
res.status(500).json({ error: err.message });
}
} else {
res.status(400).send("URL inválida");
}
}
En el lado del cliente manipulo las respuestas enviadas por el servidor:
fetch(url)
.then((response) => response.json())
.catch(function () {
window.location.href = "/muestra_imagen?imagen=error_url";
})
.then(function (data) {
if (data.error) {
window.location.href =
"/muestra_imagen?imagen=error_servidor&error=" + data.error;
} else {
window.location.href = "/muestra_imagen?imagen=" + data.imagen;
botonSubmit.attr("disabled", false);
botonSubmit.html("Subir Imagen al Servidor");
loader.hide();
}
});
4.La imagen alterada debe ser almacenada con un nombre incluya una porción de un UUID y con extensión “jpg”, por ejemplo: 3dcb6d.jpeg. (2 Puntos)
Para generar el ID único utilizo la siguiente función:
function generarID() {
return uuidv4().slice(0, 6);
}
Y creo la ruta de la imagen utilizando dicha función:
const nombreImagen = `img${generarID()}.jpg`;
A los 5 minutos elimino todos los archivos creados en el servidor en la carpeta images la cual es la que almacena los archivos creados usando Jimp:
function eliminarArchivosDeCarpeta() {
const carpeta = path.join(__dirname, "..", "images");
fs.readdir(carpeta, (err, archivos) => {
if (err) {
console.error("Error al leer el directorio:", err);
return;
}
archivos.forEach((archivo) => {
const rutaArchivo = path.join(carpeta, archivo);
fs.unlink(rutaArchivo, (err) => {
if (err) {
console.error("Error al eliminar el archivo:", err);
} else {
console.log("Archivo eliminado:", rutaArchivo);
}
});
});
});
}
setInterval(eliminarArchivosDeCarpeta, 5 * 60 * 1000);