From e779489510593253aaafc1ac6a39ae26207f7fa1 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 6 Jul 2021 15:58:27 +0000 Subject: [PATCH] 2021-07-06 --- docs/index.html | 1634 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1634 insertions(+) create mode 100644 docs/index.html diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..86156f4 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,1634 @@ + + + + + RSSPaper + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

RSSPaper

+

~ My static generate newspaper ~

+
+
+
+ + +
+
+ +

+ Comisiones cuando vendes en Apple Store +

+ +
+

Comisiones cuando vendes en Apple Store

+

Programador Web Valencia

+
+
+
+

Comisión

+ +

¿Quieres vender en la Apple Store? Lo siento pero tenemos que hablar.

+ +

Cuando decides poner a la venta algún elemento dentro de un App no todas las ganancias van a tu bolsillo. Dependiendo de ciertas variables Apple se llevará un porcentaje por cada transacción, que puede ser de un 0% (ninguna), 15% o un 30%.

+ +

Un ejemplo rápido. Acabas de publicar un App de cocina donde ofreces deliciosas recetas veganas para perros. Decides que la vas a monetizar por media de una suscripción a un precio de 10 euros al mes. Solamente quienes paguen podrán visualizar las recetas completas con todos sus pasos; el resto únicamente disfrutaran del primer paso. En este caso de cada suscripción a ti te llegará 7 euros (un 70%) mientras que Apple se quedará una comisión de 3 euros (un 30%). Y esta situación ser repetirá en cada usuario y renovación.

+ +

Existen 2 servicios que no debes confundir, ya que su uso es completamente diferente a pesar que ambos gestionen dinero.

+ +
    +
  • +

    Apple Pay: Implementación para hacer pagos en una web o App por medio de una tarjeta que ha sido vinculada con la cartera de Apple.

    +
  • +
  • +

    In-App Purchase: Implementación para realizar pagos dentro de un App. Orientado a ofrecer contenido como: productos digitales, suscripciones y contenido premium.

    +
  • +
+ +

El último servicio es el que nos interesa. Dentro podremos encontrar 3 subcategorías de posibles pagos:

+ +
    +
  • Consumibles: como gemas en un videojuego o incrementar la visibilidad de un perfil temporalmente en un red de citas.
  • +
  • No consumibles: características premium que son compradas en una ocasión y no expiran.
  • +
  • Suscripciones: características premium o acceso a contenido a través de un pago recurrente. Cuando el usuario decide cancelar el siguiente pago, estas características dejan de ser accesibles transcurrido el periodo pagado.
  • +
+ +

Es importante que sepas donde encaja el App en estas subcategorías porque las comisiones cambiarán.

+ +

Comisiones

+ +
    +
  • El App es gratis en tienda, no se vende nada: 0%.
  • +
  • El App es gratis en tienda pero posee anuncios: 0%.
  • +
  • El App es gratis en tienda pero se vende productos o servicios físicos: 0%.
  • +
  • El App es gratis en tienda aunque puedes pagar por consumibles: 30%.
  • +
  • El App es de pago, no se vende nada: 30%.
  • +
  • El App es gratis en tienda aunque puedes pagar una suscripción: 30%, aunque después del primer año baja a 15%.
  • +
  • Existe pagos o suscripciones fuera del App: 0%, sin embargo no debe existir ningún enlace o referencia al lugar donde se pueden realizar los pagos.
  • +
  • Existen pagos o suscripciones fuera del App con posibilidad de hacerlo también dentro de un dispositivo Apple: 0% si no es en el ecosistema de Apple, dentro del App se debe pagar las comisiones anteriormente mencionadas.
  • +
+ +

Tabla de precios disponibles

+ +

Los precios no los eliges libremente, Apple te da una tabla de posibilidades que si o si debes seleccionar la opción que más se ajuste con tu negocio. Te aviso que las cantidades a percibir varían dependiendo del país. Puede darse el caso que marques 10 euros, pero en un lugar como la India se venda por 4 euros.

+ +

Tabla precios In-App

+ +

Otras comisiones

+ +

No olvides que independientemente de Apple debes integrar una pasarela de pago. Alguien debe gestionar el movimiento de dinero entre la tarjeta del cliente y tu cuenta bancaria. Corre por tu cuenta. Las más populares son las siguientes.

+ +
    +
  • Stripe: Se lleva una comisión de 1,4 % + 0,25 € para tarjetas europeas y 2,9 % + 0,25 € para tarjetas no europeas.
  • +
  • Paypal: Se lleva una comisión de 2,8 % + una tarifa fija dependiendo de la moneda.
  • +
+ +

Sin olvidar el pago anual de Apple Developer Program, que son 100 dolares. Es el precio para que tu App esté accesible en la tienda. En caso de no pagarlo sería retirada.

+ +

Y por último los impuestos locales de cada país. Pero esto es inabarcable de explicar en un artículo de blog.

+ +

Conclusión

+ +

Para publicar un App en la Apple Store debemos tener en cuenta las siguientes comisiones.

+ +
    +
  • Apple Developer Program: 100 dolares anuales.
  • +
  • In-App Purchase: Entre 0% al 30%.
  • +
  • Pasarela de pagos: Los mencionados rondan de entre 1,4% al 2.9% + una tarifa fija.
  • +
  • Reducción de precio en algunos países.
  • +
  • Impuestos locales.
  • +
+ +

Aún así, sigue siendo la plataforma más rentable dentro del desarrollo de Apps.

+ +

Más información

+ +

Todas las funciones: In‑App Purchase

+ +

Comisiones: Principales prácticas

+ +
+
+ + + +
+
+ +

+ Don Clojure de la Mancha +

+ +
+

Don Clojure de la Mancha

+

Programador Web Valencia

+
+
+
+

Don Clojure de la Mancha

+ +

Próximamente será publicado el libro: Don Clojure de la Mancha. ¿Quieres ser el primero en enterarte? Tan solo debes dejar un comentario. El email que introduzcas no será visible y solo le daré uso para avisarte del momento y lugar. NO TE ESTAS SUSCRIBIENDO A UNA NEWSLETTER.

+ +

Gracias por apoyar al software libre, la programación funcional y la comunidad hispana de Clojure.

+ +
+
+ + + +
+
+ +

+ Django ordenar ignorando los acentos +

+ +
+

Django ordenar ignorando los acentos

+

Programador Web Valencia

+
+
+
+

Django con acento

+ +

En caso que intentes ordenar una consulta de la base de datos y no uses PosgreSQL como base de datos principal te vas a encontrar un pequeño problema: Cuando hay acentos no se ordena de una forma lógica. Si utilizas SQLite te lo habrás encontrado de frente. Por ejemplo, si yo tengo una tabla con nombres e intento ordenarlas con order_by pasaré de:

+ +
Zaragoza, Ávila, Murcia, Albacete...
+
+ +

al siguiente orden

+ +
Albacete, Murcia, Zaragoza, Ávila...
+
+ +

Las palabras con acento, con ñ u otros carácteres acabarán al final de la lista.

+ +

Para arreglarlo he creado la siguiente solución que debes copiarlo en el archivo donde necesites realizar el orden deseado.

+ +
import re
+import functools
+
+
+def order_ignore_accents(queryset, column):
+    """Order Queryset ignoring accents"""
+
+    def remove_accents(raw_text):
+        """Removes common accent characters."""
+        sustitutions = {
+            "[àáâãäå]": "a",
+            "[ÀÁÂÃÄÅ]": "A",
+            "[èéêë]": "e",
+            "[ÈÉÊË]": "E",
+            "[ìíîï]": "i",
+            "[ÌÍÎÏ]": "I",
+            "[òóôõö]": "o",
+            "[ÒÓÔÕÖ]": "O",
+            "[ùúûü]": "u",
+            "[ÙÚÛÜ]": "U",
+            "[ýÿ]": "y",
+            "[ÝŸ]": "Y",
+            "[ß]": "ss",
+            "[ñ]": "n",
+            "[Ñ]": "N",
+        }
+        return functools.reduce(
+            lambda text, key: re.sub(key, sustitutions[key], text),
+            sustitutions.keys(),
+            raw_text,
+        )
+
+    return sorted(queryset, key=lambda x: remove_accents(eval(f"x.{column}")))
+
+ +

Supongamos, por ejemplo, que necesitas ordenar unos pueblos o municipios. Lo que haría cualquier desarrollador es:

+ +
towns = Town.objects.all().order_by('name')
+
+ +

En su lugar, omitirás order_by y añadirás la consulta a la función order_ignore_accents. Y como segundo argumento la columna que quieres usar para ordenar. En este caso será name.

+ +
towns_order = order_ignore_accents(Town.objects.all(), 'name')
+
+ +

Se ordenará como esperamos.

+ +
Albacete, Ávila, Murcia, Zaragoza...
+
+ +
+
+ + + +
+
+ +

+ Tutorial rápido de Twing para PHP +

+ +
+

Tutorial rápido de Twing para PHP

+

Programador Web Valencia

+
+
+
+

Twing

+ +

Trabajar con un motor de plantillas en PHP simplifica la labor de concadenar variables en ficheros con mucho texto, como puede ser un html. Cualquier Framework que imagines incorpora un sistema similar pero podemos usarlo de manera independiente para pequeñas páginas o funcionalidades.

+ +

Primero debemos instalar Twig en su versión más reciente en la raíz del proyecto. Esto lo podemos realizar con composer.

+ +
composer require "twig/twig:^3.0"
+
+ +

Ahora creamos una carpeta donde almacenaremos todas las plantillas.

+ +
mkdir templates
+
+ +

Dentro creamos el archivo contacto.txt con el siguiente contenido.

+ +

+Hola {{ nombre }},
+gracias por escribirnos desde {{ email }} con el asunto "{{ asunto }}".
+¡Nos vemos!
+
+
+ +

Como es un ejemplo, vamos a crear otro archivo, llamado contacto.html, con el contenido:

+ +

+<h1>Hola {{ nombre }},</h1>
+<p>gracias por escribirnos desde {{ email }} con el asunto "{{ asunto }}".</p>
+<p>¡Nos vemos!</p>
+
+
+ +

Todas las variables entre {{ }} serán sustituidas por las variables que se definan. Si no ha quedado claro en breve lo entenderás.

+ +

En estos momentos disponemos de 2 plantillas con diferentes extensiones y formatos. No es obligatorio disponer de varias plantillas, busque aprecies que funciona de manera independiente con cualquier formato en texto plano.

+ +

Ahora creamos un archivo PHP donde ejecutaremos el código. Podemos llamarlo, por ejemplo, renderizar.php. Añadimos:

+ +
// Cargamos todas las extensiones. En este caso solo disponemos de Twig
+require_once('vendor/autoload.php');
+// Indicamos en Twig el lugar donde estarán las plantillas.
+$loader = new \Twig\Loader\FilesystemLoader('templates');
+// Cargamos las plantillas al motor de Twig
+$twig = new \Twig\Environment($loader);
+// Definimos las variables que deseamos rellenar en las plantillas.
+$variablesEmail = [
+    'nombre' => 'Cid',
+    'email' => 'cid@campeador.vlc',
+    'asunto' => 'Reconquista'
+];
+// Renderizamos con la plantilla 'contacto.txt'
+$plantillaPlana =  $twig->render('contacto.txt', $variablesEmail);
+// Renderizamos con la plantilla 'contacto.html'
+$plantillaHTML =  $twig->render('contacto.html', $variablesEmail);
+
+ +

Si yo hiciera un echo de cada variable podemos ver el trabajo realizado.

+ +
echo $plantillaPlana;
+/**
+Hola Cid,
+gracias por escribirnos desde cid@campeador.vlc con el asunto "Reconquista".
+¡Nos vemos!
+**/
+
+ +
echo $plantillaHTML;
+/**
+<h1>Hola Cid,</h1>
+<p>gracias por escribirnos desde cid@campeador.vlc con el asunto "econquista".</p>
+<p>¡Nos vemos!</p>
+**/
+
+ +

Y eso es todo.

+ +

Es realmente interesante para trabajar con emails, plantillas más complejas o en la búsqueda de renderizar un PDF. Sea cual sea tu objetivo final, disponer de un motor de plantillas en PHP hará más fácil tu trabajo.

+ +
+
+ + + +
+
+ +

+ Cómo cargar variables de entorno para un Back-End +

+ +
+

Cómo cargar variables de entorno para un Back-End

+

Programador Web Valencia

+
+
+
+

Enviroment

+ +

Una buena práctica es no dejar secretos, como contraseñas o Tokens, dentro del código. Y ni mencionar el peligro que conlleva subirlo a un repositorio. En gran medida se hace hincapié en esta omisión de variables por no dejar expuesto al resto del equipo un contenido sensible. Además otorga la posibilidad de jugar con diferentes credenciales durante el desarrollo, algunas pueden ser solo para hacer pruebas y otras las que serán usadas en el proyecto final.

+ +

Muchos Frameworks ya incorporan un sistema similar al que vamos a mencionar. En breve descubrirás que la técnica es tan sencilla que puedes montártelo por tu cuenta.

+ +

Primero crea un archivo plano con el siguiente contenido. Yo lo llamaré: .env

+ +
TOKEN=123456789
+USER=TUX
+PASSWORD=qwe123
+
+ +

Son 3 futuras variables de entorno con sus valores.

+ +

A continuación ejecuta el siguiente comando en el terminal, en la misma carpeta donde se encuentra el fichero. Convertirá cada línea del fichero en una variable de entorno.

+ +
export $(cat .env | egrep -v "(^#.*|^$)" | xargs)
+
+ +

Si quieres comprobar que se ha ejecutado correctamente puedes hacer un echo con cualquier variable añadiendo el prefijo $.

+ +
echo $TOKEN
+
+ +
123456789
+
+ +

Tarea terminada. Recuerda que si cierras el terminal o modificas el archivo, debes volver a ejecutar el comando.

+ +

Leer variables de entorno en PHP

+ +
$token = getenv('TOKEN');
+$user = getenv('USER');
+$password = getenv('PASSWORD');
+
+echo $token;
+// 123456789
+
+ +

Leer variables de entorno en Python

+ +
import os
+
+token = os.getenv('TOKEN')
+user = os.getenv('USER')
+password = os.getenv('PASSWORD')
+
+ +

Leer variables de entorno en Clojure

+ +
(def token (System/getenv "TOKEN"))
+(def user (System/getenv "USER"))
+(def password (System/getenv "PASSWORD"))
+
+ +

Aunque también puedes usar la dependencia environ.

+ +

Añade en project.clj.

+ +
[environ "0.5.0"]
+
+ +

Y usa con total libertad.

+ +
(require [environ.core :refer [env]])
+
+(def token (env :TOKEN))
+(def user (env :USER))
+(def password (env :PASSWORD))
+
+ +
+
+ + + +
+
+ +

+ Comandos esenciales de un Full Stack en Linux +

+ +
+

Comandos esenciales de un Full Stack en Linux

+

Programador Web Valencia

+
+
+
+

Terminal

+ +

Si quieres ser un buen desarrollador Web, o simplemente un usuario de Linux competente, defenderte con el terminal es básico. Por suerte gran parte de estos comandos pueden ser utilizados entre diversos sistemas operativos como Linux, BSD, MacOS X y Windows 10 a través de Shell. Son un estándar para profundizar en tareas, trabajar rápidamente y ir directo a una funcionalidad.

+ +

Por ello mismo dejo una lista de los comandos que creo esenciales para un Fullstack: manipular documentos, archivos, directorios, búsquedas, trabajar con logs, instalar servicios… etc. A partir de aquí ya puedes ir creciendo.

+ +

ls

+ +

Lista carpetas y archivos de un directorio.

+ +
ls
+
+ +

Muestra más información.

+ +
ls -l
+
+ +

Incluye los archivos ocultos.

+ +
ls -a
+
+ +

mkdir

+ +

Crea carpetas.

+ +
mkdir nueva_carpeta
+
+ +

Crea directorios recursivamente.

+ +
mkdir -p carpeta1/carpeta2
+
+ +

less

+ +
less archivo.txt
+
+ +

touch

+ +

Crea un archivo vacío.

+ +
touch archivo.txt
+
+ +

cd

+ +

Cambia de directorio.

+ +
cd carpeta
+
+ +

Subir un nivel

+ +
cd ..
+
+ +

Retroceder un directorio (subir al padre)

+ +
cd ..
+
+ +

Directorio del usuario

+ +
cd ~
+
+ +

Volver al directorio anterior

+ +
cd -
+
+ +

Ver información

+ +

Muestra información de un archivo o carpeta.

+ +
file paris.jpg
+
+ +

Buscar

+ +

Buscar archivos o carpetas.

+ +

Un fichero

+ +
find carpeta-donde-buscar -name feliz.jpg
+
+ +

Solo directorios

+ +
find carpeta-donde-buscar -type d -name vacaciones
+
+ +

pwd

+ +

Muestra la ruta absoluta del directorio donde nos encontramos.

+ +
pwd
+
+ +

mv

+ +

Mueve o renombra un archivo o carpeta.

+ +
mv fichero_original.txt fichero_nuevo_nombre.txt
+
+ +

cp

+ +

Copia un archivo o carpeta.

+ +
cp texto.txt texto_copiado.txt
+
+ +

Copia una carpeta

+ +
cp -r carpeta carpeta_copiada
+
+ +

rm

+ +

Borra un archivo

+ +
rm archivo.txt
+
+ +

Borrar carpeta

+ +
rm -r carpeta
+
+ +

Fecha

+ +

Ver la fecha

+ +
date
+
+ +

Convertir tiempo de formato unix a humano

+ +
date -r 1619018708
+
+ +

Nombre de usuario

+ +
whoami
+
+ +

tar

+ +

Comprime o descomprime archivos en formato Linux: tar, gzip y bz2.

+ +

Ver aquí

+ +

grep

+ +

Imprime el contenido de un archivo filtrando por un patrón.

+ +

Filtrar el resultado de un comando

+ +
ls | grep texto
+
+ +

Filtrar un archivo

+ +
cat archivo.txt | grep texto
+
+ +

sudo/su

+ +

Ejecuta comando con otros permisos, como administrador u otro usuario.

+ +

chmod

+ +

Cambia los permisos de un archivo o carpeta.

+ +
chmod 744 script.sh
+
+ +

Otra forma es utilizado un trio con:

+ +

Rol

+ +
    +
  • +

    u → usuario

    +
  • +
  • +

    g → grupo

    +
  • +
  • +

    o → Otros

    +
  • +
  • +

    a → Todos

    +
  • +
+ +

Acción

+ +
    +
  • +

    + → Añadir

    +
  • +
  • +

    - → Quitar

    +
  • +
+ +

Permiso

+ +
    +
  • +

    r → Lectura

    +
  • +
  • +

    w → Escritura

    +
  • +
  • +

    x → Ejecución

    +
  • +
+ +

Por ejemplo, se le quita el permiso de escritura a todos

+ +
chmod a-w first.txt
+
+ +

Al usuario se le da permisos de ejecución

+ +
chmod u+x script.sh
+
+ +

chown

+ +

Cambia propiedad de un archivo o carpeta.

+ +
chmod debian:debian archivo.txt
+
+ +

cat

+ +

Concadena archivos.

+ +
cat archivo1.txt archivo2.txt
+
+ +

echo

+ +

Imprime el contenido de un archivo.

+ +
echo archivo.txt
+
+ +

man

+ +

Muestra el manual de un comando.

+ +
man ls
+
+ +

history

+ +

Muestra el historial de comandos.

+ +
history
+
+ +

clear

+ +

Limpia el terminal.

+ +
clear
+
+ +

reboot

+ +

Reinicia.

+ +
sudo reboot
+
+ +

shutdown

+ +

Apaga.

+ +
sudo shutdown now
+
+ +

top/htop

+ +

Monitor de procesos.

+ +
htop
+
+ +

nano

+ +

Editor de archivos simple.

+ +
nano archivo.txt
+
+ +

vim/nvim/emacs

+ +

Editor de archivos avanzado.

+ +
emacs -nw archivo.txt
+
+ +

curl

+ +

Realiza peticiones HTTP.

+ +
curl programadorwebvalencia.com
+
+ +

tail

+ +

Muestra el final de un archivo.

+ +
tail archivo.txt
+
+ +

ip

+ +

Muestra información de tu red.

+ +
ip address show eth0
+
+ +

lsof

+ +

Muestra que servicio esta utilizando cierto puerto.

+ +
lsof -i tcp:80
+
+ +

df

+ +

Muestra la información de espacio ocupado en el disco.

+ +
df -h
+
+ +

du

+ +

Muestra el espacio que ocupa los diferentes elementos de una carpeta.

+ +

Solo un nivel y en formato humano

+ +
du -d 1 -h
+
+ +

journalctl

+ +

Muestra los logs en tiempo real.

+ +
journalctl -f
+
+ +

Muestra los logs en tiempo real de un servicio.

+ +
journalctl -f -u ssh
+
+ +

Muestra los logs de un servicio.

+ +
journalctl -u ssh
+
+ +

Muestra las últimoas 20 líneas de un log.

+ +
journalctl -n 20
+
+ +

Limpia los logs hasta alcanzar el peso que indiques.

+ +
journalctl --vacuum-size=1G
+
+ +

Borra los logs con más de cierto tiempo.

+ +
journalctl --vacuum-time=1years
+
+ +

Ejecutar último comando

+ +
!!
+
+ +

Ejecuta último comando con sudo.

+ +
sudo !!
+
+ +
+
+ + + +
+
+ +

+ ¿Qué hacer después de instalar Debian en un VPS o servidor? +

+ +
+

¿Qué hacer después de instalar Debian en un VPS o servidor?

+

Programador Web Valencia

+
+
+
+

Logo Debian

+ +

Estos son todos los pasos que realizo cuando creo un VPS o servidor en Debian. A lo largo del tiempo he ido añadiendo puntos, modificando y quitando elementos innecesarios; por lo que no lo percibáis como “La guía definitiva”. Sino más bien como unos “apuntes de apoyo”. Personalmente ejecuto todo, aunque cada proyecto es un desafío diferente.

+ +

1. Actualizar a la última versión y estable

+ +
apt update && \
+apt upgrade -y && \
+apt dist-upgrade
+
+ +

2. Instalar software mínimo

+ +
apt install -y build-essential fail2ban iptables-persistent msmtp-mta python3-dev python3-pip libcurl4-openssl-dev libssl-dev htop git neovim wget curl zsh tmux && \
+sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" && \
+apt autoremove -y
+
+ +

3. Configurar el cortafuegos

+ +

Dejamos pasar 80 y 443 para permitir los protocolos http y https.

+ +
iptables -A INPUT -p tcp --dport 80 -j ACCEPT &&
+iptables -A INPUT -p tcp --dport 443 -j ACCEPT
+
+ +

4. Cambiar editor por defecto

+ +
update-alternatives --config editor
+
+ +

5. Ajustar la hora

+ +

En este ejemplo configura la hora a Madrid (España).

+ +
ln -fs /usr/share/zoneinfo/Europe/Madrid /etc/localtime && \
+dpkg-reconfigure -f noninteractive tzdata
+
+ +

6. Activa las actualizaciones automáticas de seguridad no atendidas

+ +
apt install -y unattended-upgrades apt-listchanges && \
+echo unattended-upgrades unattended-upgrades/enable_auto_updates boolean true | debconf-set-selections && \
+dpkg-reconfigure -f noninteractive unattended-upgrades
+
+ +

7. Crea un usuario

+ +

Se llamará debian, aunque puedes llamarlo como desees.

+ +
useradd --shell /bin/zsh -m debian
+
+ +

Ahora nos metemos en el usuario.

+ +
su debian
+
+ +

Configurarmos las claves ssh y oh-my-zsh.

+ +
ssh-keygen -t rsa
+exit
+
+ +

Lo añadimos al grupo de sudo.

+ +
usermod -a -G sudo debian
+
+ +

Entramos en visudo para permitirle ejecutar sudo.

+ +
visudo
+
+ +

Editando la siguente línea.

+ +
%sudo   ALL=(ALL:ALL) NOPASSWD:ALL
+
+ +

Generamos la keygen de ssh para entrar en un futuro.

+ +

Copiamos las autorizaciones actuales asociadas con root.

+ +
cp /root/.ssh/authorized_keys /home/debian/.ssh/ && \
+chown debian:debian /home/debian/.ssh/authorized_keys
+
+ +

8. Medida de seguridad ante disco lleno

+ +

Añadimos una archivo con contenido aleatorio de, por ejemplo, 1Gb. En caso que se llene el disco, podremos borrarlo para tener un margen de acción.

+ +
dd if=/dev/urandom of=balloon.txt bs=1MB count=1000
+
+ +

9. Limita el espacio de los logs

+ +

Editas

+ +
nano /etc/systemd/journald.conf
+
+ +

Descomentas (quitas la #) a la vez que modificas la siguiente línea.

+ +
SystemMaxUse=1Gb
+
+ +

Para terminar reinicia el servicio.

+ +
systemctl restart systemd-journald
+
+ +

Extras

+ +

Instalar docker

+ +
apt update && \
+apt install -y \
+    apt-transport-https \
+    ca-certificates \
+    curl \
+    gnupg \
+    lsb-release && \
+curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \
+echo \
+  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
+  $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \
+apt update && \
+apt -y install docker-ce docker-ce-cli containerd.io docker-compose
+
+ +

Activar Swap

+ +

Habilitamos un espacio reservado en el disco en caso de que la RAM se llene.

+ +

Instalamos zram.

+ +
sudo apt install zram-tools
+
+ +

Editamos su configuración.

+ +
sudo nano /etc/default/zramswap
+
+ +

Le marcamos que su capacidad sea la mitad de la RAM.

+ +
PERCENTAGE=50
+ALLOCATION=4096 #4Mb
+ALLOCATION=8192 #8Mb
+
+ +

Instalar snap

+ +
sudo apt install snapd
+
+ +
+
+ + + +
+
+ +

+ Comandos para comprimir y descomprimir +

+ +
+

Comandos para comprimir y descomprimir

+

Programador Web Valencia

+
+
+
+

Comprimir

+ +

Dentro de Linux y MacOS disponemos de una herramientas preinstalada que es fantásticas para comprimir y descomprimir cualquier tipo de archivo: fotos, vídeos, texto, carpetas… Con solo tar ya podremos realizar las tareas básicas.

+ +

Conceptos importantes.

+ +
    +
  • tar: Tarro o contenedor. Sirve para agrupar un conjuntos de archivos, no comprime.
  • +
  • gzip: Algoritmo de compresión malo pero rápido. Equivalente a un zip.
  • +
  • bz2: Algoritmo de compresión bueno pero lento. Equivalente a un rar.
  • +
+ +

Comprimir

+ +

tar

+ +

Ejemplo de como crear un grupo o archivador usando tar.

+ +
tar -cvf nombre.tar carpetas-o-archivos
+
+ +

c —> Crea un archivador (tar).

+ +

v —> Muestra el progreso.

+ +

f —> Indicamos que vamos a especificar el nombre final.

+ +

gzip

+ +

Ejemplo de como comprimir creado un zip equivalente en Linux.

+ +
tar -czvf futuro-comprimido.tar.gz carpetas-o-archivos-a-comprimir
+
+ +

c —> Crea un archivador (tar).

+ +

z —> Comprime usando gzip (zip)

+ +

v —> Muestra el progreso.

+ +

f —> Indicamos que vamos a especificar el nombre final.

+ +

bz2

+ +

Ejemplo de como comprimir creado un rar equivalente en Linux. (sustituye z por j)

+ +
tar -cjvf futuro-comprimido.tar.bz2 carpetas-o-archivos-a-comprimir
+
+ +

c —> Crea un archivador (tar).

+ +

j —> Comprime usando bzip2 (equivalente a rar)

+ +

v —> Muestra el progreso.

+ +

f —> Indicamos que usaremos un archivo.

+ +

Descomprimir

+ +

Ejemplo de como descomprimir cualquier formato: tar, tar.gz o tar.bz2. (sustituye c por x)

+ +
tar -xvf comprimido.tar.gz
+
+ +

x —> Extrae.

+ +

v —> Muestra el progreso.

+ +

f —> Indicamos que usaremos un archivo.

+ +
+
+ + + +
+
+ +

+ Cómo suavizar un scroll +

+ +
+

Cómo suavizar un scroll

+

Programador Web Valencia

+
+
+
+

cookie

+ +

Si queremos que al pulsar en un hipervínculo, o ancla, se desplace de manera suave y lenta, en lugar ser instantáneo, podemos optar por usar algunos de siguientes 3 trucos. Pasando por CSS, JavaScript o JQuery. El artículo no cubre la forma de realizar un ancla, aunque puedes aprender en mi curso gratuito de HTML.

+ +

DEMO

+ + + +

Versión solo con CSS

+ +

Al añadir el siguiente CSS conseguirás que los movimientos de tus anclas sean suaves en lugar de instantáneos.

+ +
body {
+	scroll-behavior: smooth;
+}
+
+ +

En el momento que se escribió este artículo no era compatible con Safari.

+ +

Versión solo con JavaScript Vainilla

+ +

En caso contrario de que no funcione como esperas podrás usar un poco de JavaScript para conseguir el mismo efecto.

+ +
<script>
+	document.addEventListener('DOMContentLoaded', () => {	
+
+	    	//===
+		// SCROLL SMOOTH
+		//===
+		// Variables
+		const links = document.querySelectorAll('a[href *= "#"]:not([href = "#"])');
+
+		/**
+		 * Event scroll
+		 */
+		function clickHandler(event) {
+		  event.preventDefault();
+		  const href = this.getAttribute("href");
+		  const offsetTop = document.querySelector(href).offsetTop;
+
+		  scroll({
+		    top: offsetTop,
+		    behavior: "smooth"
+		  });
+		}
+
+		// Add event all links
+		links.forEach((link) => link.addEventListener("click", clickHandler));
+	});
+</script>
+
+ +

Versión solo con JQuery

+ +

Y por último, en caso de que aún así no funcione; puedes recurrir a un clásico que nunca te va a fallar y ha sido utilizado durante muchos años.

+ +
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
+<script>
+	$(function() {
+	    $('a[href *= "#"]:not([href = "#"])').click(function() {
+				if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
+					let target = $(this.hash);
+		    target = target.length ? target : $('[name = ' + this.hash.slice(1) + ']');
+		    if (target.length) {
+			$('html, body').animate({
+			    scrollTop: target.offset().top
+			}, 1000);
+			return false;
+		    }
+		}
+	    });
+	});
+</script>
+
+ +

Obviamente necesitarás que esté presente JQuery en tu proyecto web.

+ +
+
+ + + +
+
+ +

+ HTML sobre WebSockets +

+ +
+

HTML sobre WebSockets

+

Programador Web Valencia

+
+
+
+

WebSockets sobre HTML

+ +

La forma tradicional de conseguir una SPA (Single-page Application) es dividir las responsabilidades, el Back-End sirve la información y el Front-End la dibuja dinámicamente. Tristemente implica un doble esfuerzo en el desarrollo siendo necesario la creación de 2 aplicaciones con tecnologías diferentes aumentando costes e involucrando a dos perfiles especializados. Aunque, por supuesto, es el precio que debemos pagar si queremos una web en tiempo real y que se renderice en un pestañeo. ¿O hay una alternativa? ¿Con incluso mejor rendimiento? Así es, y además es más fácil de desarrollar al trabajar con un solo lenguaje. Esta arquitectura se denomina: HTML sobre WebSockets.

+ +

Chris McCord, creador de Phoenix (el Framework más popular dentro del ecosistema Elixir), presentó en ElixirConf 2019 una tecnología llamada LiveView. En apenas 15 minutos creó un clon de Twitter que funcionaba en tiempo real sin necesidad de incorporar JavaScript renderizador o un framework popular (React, Angular, Vue…) que gestione la Vista, demostrando que era posible quedarse en el Back-End y lograr productividad con una dulce aroma a buen rendimiento. Desde entonces se ha popularizado esta solución, inspirado a otros desarrolladores para crear implementaciones de HTML sobre WebSockets en otros lenguajes. Se puede volver al Back-End pero sin renunciar a lo bueno del Front-End.

+ +

¿Cómo funciona?

+ +

Disclamer: ¡si se usa JavaScript! Su labor no es renderizar sino crear un canal de comunicación con WebSockets y situar el HTML recibido en el lugar adecuado. Además de otras tareas secundarias como animaciones, gestión de eventos, etc.

+ +

La solución de McCord es no enviar al Front-End un JSON, sino HTML que no necesite ser preprocesado. De ese modo trasladamos la carga del dibujado, y toda su lógica, al Back-End. Ya pero… ¿Cómo hacemos que el servidor nos envíe nuevo contenido de forma inmediata y sin realizar una petición? Sencillo: con WebSockets.

+ +

Repasemos el sistema tradicional de la introducción. Desde la Web hago una petición HTTP, el navegador inicia la acción, obteniendo en la respuesta un JSON con toda la información en crudo. Lo siguiente es interpretar y crear el HTML correspondiente.

+ +

Tradicional

+ +

Mientras que HTML sobre WebSockets puede ser el envío de un JSON donde se devuelve HTML/CSS/JS. O incluso puede quitar el propio envío quedando a la escucha.

+ +

Protocolo WebSockets sobre HTML

+ +

Veamos el ejemplo donde se renderiza el artículo número 2 de un blog.

+ +

1. Conectamos

+ +

Partimos con una conexión. Ya hay un tubo de comunicación entre cliente y servidor.

+ +

Conectar con WebSockets

+ +

2. Petición de componente

+ +

El cliente pide el contenido de la ruta “/articulo/2/” a través del canal.

+ +

Pedir WebSockets sobre HTML

+ +

3. Recepción de HTML/CSS/JS

+ +

El servidor genera el HTML/CSS/JS, usando el sistema de plantillas del Back-End, y lo devuelve por el canal.

+ +

Recibir WebSockets sobre HTML

+ +

4. Impresión

+ +

Por último, el Front-End lo sitúa en el lugar adecuado o asignado.

+ +

¿Dónde puedo ver una demostración?

+ +

He creado un prototipo en Django de un Blog con 100 entradas, cada artículo esta relacionado con sus respectivos comentarios. Además existe un apartado para visualizar el artículo completo, un paginador y una sección estática con algunos párrafos.

+ + + +

Aquí puedes ver como los cambios son reflejados en todos los clientes.

+ + + +

Si observáis la url, nunca se cambia de página, y… ¡aun así funciona! ¿Quieres probarlo por ti mismo? Tienes la posibilidad de levantarlo a partir del código fuente en GitHub, esta Docketizado a un comando de distancia para arrancarlo.

+ +

¿Cuáles son sus ventajas?

+ +
    +
  • Solo hay un motor de renderizado, simplificando la tarea.
  • +
  • Real-time, los clientes reciben los cambios tan rápido como sea posible.
  • +
  • El protocolo WebSockets es más rápido que HTTP. Fuente: starkoveflow
  • +
  • Apropiado para conexiones lentas. Fuente: browsee.
  • +
  • Crear un SPA sin apenas JavaScript.
  • +
  • Excelente SEO, los motores de búsqueda adorarán la página al encontrarse solo HTML.
  • +
+ +

¿Cuáles son sus inconvenientes?

+ +
    +
  • El servidor necesitará más recursos al tener que dejar un WebSocket abierto por cliente.
  • +
  • Poca documentación al respecto.
  • +
  • Pocos frameworks.
  • +
+ +

¿Qué Frameworks existen?

+ +

Puedes empezar por los siguientes recursos.

+ +
    +
  • Elixir/Phoenix: LiveView.
  • +
  • Python/Django: Sockpuppet y Reactor.
  • +
  • C#/.NET: Blazor Server.
  • +
  • JavaScript: Turbo con Stimulus
  • +
+ +

Apuntes finales

+ +

No creo que sea la solución definitiva, pero merece ser escuchada. Es llamativo su creciendo adopción y herramientas que están apareciendo. A nivel personal se sorprendió lo poco conocido que es, posiblemente a causa del poderoso ecosistema de JavaScript. Sin embargo es todo un placer no estar en la carrera de fondo que supone el Front-End para no quedarte desactualizado, y centrarte en el lenguaje de servidor.

+ +

En serio, ¿qué puedes perder por probarlo?

+ +
+
+ + + +
+
+ +

+ Itinerario de Desarrollador Backend +

+ +
+

Itinerario de Desarrollador Backend

+

Podcast República Web

+
+
+
+ A la hora de empezar a desarrollar web, el perfil del desarrollador Backend se ve como una especialización. Donde el programador se enfoca desarrollo de API’s REST y su integración con la arquitectura de microservicios. Partiendo de la base de unos requisitos mínimos: Fundamentos de programación Programación estructurada Bases de datos relacionales Vamos a identificar tres posibles caminos: Java Javascript Python En los tres casos tendremos una buena base de programación orientada a objetos y la posibilidad de tener acceso … Ver más +
+
+ + + +
+
+ +

+ Construye tu contenido en internet con independencia de las plataformas +

+ +
+

Construye tu contenido en internet con independencia de las plataformas

+

Podcast República Web

+
+
+
+ Son tiempos de movimiento en el mundo del podcasting. Cada vez son más las iniciativas que buscan atraer y retener audiencias en el medio. Para muchos productores de contenido, el podcasting se antoja como un refugio de las guerras por el clic y la publicidad agresiva de la programática. El podcasting sigue creciendo y a esos pioneros programas amateur, se van uniendo producciones más originales y ambiciosas. Pero tanto si eres un pez grande como uno pequeño, a tus contenidos … Ver más +
+
+ + + +
+
+ +

+ Itinerario de Desarrollador Frontend +

+ +
+

Itinerario de Desarrollador Frontend

+

Podcast República Web

+
+
+
+ El perfil de Desarrollador Frontend es uno de los más populares en la industria del desarrollo de aplicaciones TIC (Tecnologías de la Información y la Comunicación, IT en inglés). Los requisitos habituales para este tipo de perfiles varían de empresa u organización pero siempre tienen una serie de aptitudes que son necesarias. Dentro de esta capacidades hay una serie de de mínimos que un futuro Desarrollador FrontEnd debe conocer, como son: Fundamentos de programación, Redes de Comunicaciones. Los fundamentos de … Ver más +
+
+ + + +
+
+ +

+ ¿Qué deberíamos exigir a un contratista en un desarrollo web? +

+ +
+

¿Qué deberíamos exigir a un contratista en un desarrollo web?

+

Podcast República Web

+
+
+
+ Cuando nos enfocamos al desarrollo software, solemos ver los requisitos que nos pone el cliente como las normas que deben guiar el proyecto que debe llevarlo a cabo. Para ello es interesante ponernos en la piel de nuestros clientes sobre lo que esperan de un contratista o un licitador. En este artículo intentaré resumir aquellos requisitos que personalmente pondría si tuviera que contratar un desarrollo a una empresa. Estos criterios podrán trasladarse de una manera efectiva y objetiva a los … Ver más +
+
+ + + +
+
+ +

+ Los podcasts que escuchamos en República Web +

+ +
+

Los podcasts que escuchamos en República Web

+

Podcast República Web

+
+
+
+ No hay persona que tenga un podcast y que a su vez no sea un oyente habitual. A menudo, incluso un oyente compulsivo. Por supuesto el equipo de República Web también tenemos una lista bastante abultada de programas que escuchamos casi siempre que podemos. El otro día propuse a mis dos compañeros, que me pasaron algunos de los que escuchan ellos y así entre los tres, poder hacer una lista de recomendaciones. El único requisito es que estuvieran relacionados con … Ver más +
+
+ + +
+
+ + +