Sábado 22 de noviembre de 2014

Miguel Ángel Useche

Miguel Ángel Useche
El weblog de Skatox » Planetas

Cómo migrar los issues de Bitbucket a Github

Hace unos días en la organización donde trabajo, nos tocó migrar de Bitbucket a Github y principalmente nuestra necesidad era migrar el código (obviamente) y la lista de issues junto con los datos asociados a ellos.

El código fuente fue sencillo pues Github tiene un asistente que permite clonar cualquier repositorio GIT y almacenarlo en el proyecto seleccionado, luego el siguiente paso fue ejecutar los siguientes comandos para cambiar el repositorio origen:

git remote set-url origin git@github.com:USUARIO/REPOSITORIO.git

Para migrar los issues, encontré un script de python para migrar los issues desde Bitbucket a Github y su uso es sencillo, sin embargo tuve problemas al ejecutarlo y me salió el error:

EOF occurred in violation of protocol

Luego de encontrar una solución en StackOverflow agregué el siguiente código luego de importar la librería SSL:

import ssl
from functools import wraps
def sslwrap(func):
    @wraps(func)
    def bar(*args, **kw):
        kw['ssl_version'] = ssl.PROTOCOL_TLSv1
        return func(*args, **kw)
    return bar

ssl.wrap_socket = sslwrap(ssl.wrap_socket)

Finalmente pude ejecutar el programa tal como lo dice su archivo README.md y en pocos segundos tuve todos los issues recreados en Github junto con los milestones y etiquetas utilizadas.

Nota: El repositorio debe ponerse temporalmente público para poder realizar la migración.

Jueves 20 de noviembre de 2014

Jesus Palencia

Acelera tu GNU/Linux con Prelink y Preload

Hoy en día es común ver PC con mas de 4 Gb de RAM usando Linux y muchas veces el usuario se pregunta como puedo hacer uso de mi hardware más eficientemente. Para lograr esto podemos hacer uso de las dos pequeñas herramientas que les mostraré a continuación.

La primera es Preload, un programa que analiza las aplicaciones que más usamos, y las pre-carga en RAM reduciendo así su tiempo de inicio al ejecutarlas.

La segunda se llama Prelink un programa que se encarga de agilizar la carga dinámica de librerías. Dicho de otro modo, rellena las tablas de símbolos del binario deduciendo las direcciones de memoria donde supuestamente van a estar los mismos, lo que resulta en una mayor velocidad de carga de las aplicaciones ya que cada vez que necesitemos un símbolo de una librería dinámica no tendremos que hacer una carga de la misma, ya que gracias a prelink sabremos donde va estar.

La instalación de ambas es bastante sencilla, solo debes ejecutar el comando correspondiente a tu distribución.

# apt -y install prelink preload

# yum install prelink preload

# pacman -S prelink preload

En el caso de preload no se necesita ninguna configuración posterior a la instalación, pero en la caso de prelink son necesarios algunos pasos adicionales.

Abrimos el archivo /etc/default/prelink

# nano /etc/default/prelink

Y modificamos las siguientes lineas:

PRELINKING=unknown

PRELINK_OPTS=-mR

Quedando ambas de la siguiente forma:

PRELINKING=yes

PRELINK_OPTS=-amR

Guardamos y ejecutamos el siguiente comando:

# prelink -amR

El proceso tomará varios minutos y al concluir la carga de las aplicaciones será mucho mas rápida.

En Debian podemos realizar un paso adicional para asegurarnos que las aplicaciones que se instalen en el futuro pasen por prelink luego del proceso de instalación.

Abrimos o creamos el archivo /etc/apt/apt.conf

# nano /etc/apt/apt.conf

Y colocamos lo siguiente:

DPkg::Post-Invoke {"echo Ejecutando prelink, espere...;/etc/cron.daily/prelink";}

Adicional a este procedimiento los usuarios de KDE pueden realizar lo siguiente para acelerar su sistema usando prelink, abrimos o creamos el archivo /etc/profile.d/kde-prelink.sh

# nano /etc/profile.d/kde-prelink.sh

Y pegamos lo siguiente:

export KDE_IS_PRELINKED=1

Luego le cambiamos los permisos a dicho archivo y listo.

# chmod 755 /etc/profile.d/kde-prelink.sh

Ya podemos reiniciar nuestro sistema y disfrutar de la carga de nuestra distribución Linux a toda velocidad.

Referencias:


Tagged: optimizaciones, prelink, preload
Jesus Palencia

Usar Hardlink para reducir el espacio ocupado en disco

Hardlink es una herramienta que detecta múltiples copias de un archivo y las reemplaza con enlaces duros, teniendo como resultado una reducción de espacio utilizado en el disco.

Su instalación es bastante simple, basta con ejecutar el comando correspondiente a tu distribución como root.

# apt -y install hardlink

# yum install hardlink

# pacman -S hardlink

Luego de su instalación basta con ejecutarlo desde la linea de comandos (como root) cada vez que desee recuperar espacio en disco.

# hardlink -f -x /sys -t -o /

La lista de opciones es un poco extensa y la podemos consultar ejecutando “man hardlink” por lo que me limitaré a explicar solo las opciones utilizada en el ejemplo.

  • -f solo trata de enlazar archivos con el mismo nombre.
  • -x excluye una carpeta del proceso de comparación (en este caso /sys)
  • -t hace la comprobación incluso cuando la fecha de modificación sea diferente.
  • -o ignora el propietario del archivo a la hora de comparar (normalmente solo se comparan archivos con el mismo dueño)
  • / le indica a hardlink que se ejecute desde la raíz del sistema de archivos.

Dependiendo de la cantidad de archivos en su disco la ejecución puede tomar bastante tiempo.

Referencias:


Tagged: filesystem, hardlink, optimizaciones

Miércoles 19 de noviembre de 2014

Fedora en el CGSOL 2014 Guatemala

Lunes 17 de noviembre de 2014

Migrando Debian a un disco SSD – Optimización básica

Usando un SSD

Mi portátil, una Thinkpad X220, venía con un disco de estado sólido (SSD) además de un disco SATA, por cosas de experimentos el disco SSD lo removí, pero encontré otro y lo agregué a mi equipo, ahora bien, ¿cómo migrar satisfactoriamente mi root system ya instalado a este nuevo SSD?.

SSD

He aquí mi breve experiencia compartida.

Instalación física del SSD

La Thinkpad viene con 2 bahías mini-PCIe, en una ya viene la tarjeta inalámbrica y trae otra vacía (lista para un modem 3G) dónde he colocado mi disco SSD, ahora bien, como es una Thinkpad tuve que “flashear” un BIOS mod (basado en 8duj25us_8DET69WW) para “eliminar” esa mala costumbre de Lenovo te poner una “lista blanca” de dispositivos que puedes meter a tu portátil (y que para colmo son más caros).

Al retirar los tornillos, se desprende la tapa que contiene el touchpad y el teclado y debajo encontrarán las bahías.

original.jpg

Para Thinkpad un disco SSD en esa bahía es tomado como secundario (sdb) y no como primario, no es ningún problema ya que en mi disco SATA /boot está separado de raíz y no pensaba migrar el arranque de allí.

 Particionando el disco

Hay 2 trucos básicos para particionar un disco de estado sólido y aprovechar al máximo su potencial:

Alineación de Particiones

Alinear las particiones es una de las actividades más importantes y menos tomada en cuenta cuando se diseña el layout de particiones, yo destiné 10GB (y realmente no necesito más para root) y para diseñarla usé parted:

parted /dev/sdb
mklabel gpt
unit s
mkpart primary 2048s 10G
align-check optimal 1

Dejamos 2048 sectores (1MB) al principio del disco, esto permite una mejor alineación del disco con el tamaño de los sectores (512Bytes):

Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number     Start   End      Size    Filesystem    Name     Flags
           17,4kB  1049kB   1031kB  Free Space
 1         1049kB  10,0GB   9999MB  ext4          primary

Dejar Holgura

Deja al menos un 10% libre al final del disco, este margen de holgura le permite al disco un “respiro” en su operación.

Además, orientadas a Linux hay otras consideraciones

NO usar SWAP

con 8GB de RAM es casi imposible que mi equipo se vaya a SWAP con la más alta demanda (viendo videos con un par de máquinas virtuales KVM en el fondo, navegando con el gran consumidor de RAM Chromium mientras chateo por Telegram), sin embargo, la ventaja de la X220 es que viene con un disco SATA, así que la SWAP se quedará en dicho disco (sólo de ser necesario).

Usar GPT

No usaré Windows ni ningún otro sistema operativo no-UNIX en este equipo, por lo que usar una geometría de particiones basada en GPT (GUID Partition Table), no solamente me permite múltiples particiones primarias, GPT almacena su tabla de particiones al principio y al final (una copia) lo que da una protección adicional para recuperación de particiones con herramientas como Testdisk.

 

Luego de particionado, procedemos a formatear.

Formato ext4

Aunque “mkfs.ext4 /dev/sdb1″ serviría para la mayoría de las opciones, en nuestro caso necesitamos activar una serie de opciones como el TRIM, con TRIM (discard: según ext4) los bloques de datos borrados o que dejan de estar en uso por el sistema operativo, el sistema puede notificarle al disco SSD que “limpie” dichos bloques inmediatamente para evitar la ralentización del mismo en operaciones de escritura futuras; además de TRIM, EXT4 no inicializa al ejecutar el comando mkfs ni la tabla de inodos ni el journal del mismo (característica conocida como “lazy initialization”) haciendo más lentas las operaciones iniciales de montaje y primera copia; por último, deseamos activar el modo WRITEBACK, con “data=writeback” los datos son escritos “después” que se ha escrito la metadata de la misma en el journal, esto tiene grandes ventajas en el performance (la operación de escritura de datos se hace en segundo plano) pero conlleva que un fallo eléctrico luego de ejecutado el commit de la metadata pero antes de finalizar la escritura de datos creará un sistema inconsistente; como me encuentro en un sistema protegido por batería (portátil), esto para mí no es un problema serio.

Sin embargo, recordemos las sabias palabras de Linus al respecto de data=writeback:

If your data gets written out long after the metadata hit the disk, you are going to hit all kinds of bad issues if the machine ever goes down. Linus

Insisto, habilitar “data=writeback” solo si tienes una garantía ABSOLUTA de que no habrán fallos del equipo durante un proceso de escritura en disco.

Para determinar si mi disco SSD soporta TRIM ejecuto:

hdparm -I /dev/sdb | grep 'TRIM'
 * Data Set Management TRIM supported (limit 2 blocks)

Luego, ejecuto entonces el formato de la partición sdb1:

mkfs.ext4 -E lazy_itable_init=0,lazy_journal_init=0 -b 4096 -m 0 -O extents,dir_index /dev/sdb1

Y tune2fs:

tune2fs -o journal_data_writeback,discard -c 5 -i 5 /dev/sdb1

Adicionalmente, bajo a 5 (del por defecto 2o) la cantidad de veces que el sistema de archivos debe ser chequeado al arranque, esto porque es un equipo que constantemente se suspende|hiberna, necesito que cada vez que arranque sea chequeado, para evitar largas esperas y que espere mucho tiempo antes que un chequeo se haga demasiado tarde y el sistema simplemente no arranque (arranque en initramfs).

Al finalizar, chequeamos:

e2fsck /dev/sdb1

Y verificamos características:

tune2fs -l /dev/sdb1 | grep discard
Default mount options: journal_data_writeback user_xattr acl discard

Ahora procedemos al montaje.

Montaje de la partición

Creamos un directorio temporal y realizamos el montaje:

mkdir /ssd
Y
mount -t ext4 /dev/sdb1 /ssd -o discard,noatime,nodiratime,nodelalloc,data=writeback,i_version,barrier=0,user_xattr,inode_readahead_blks=64,commit=100

Entre las caraterísticas del montaje están:

  • discard: habilita el TRIM de la partición
  • i_version: habilita el uso de una versión “extendida” de 64-bit de los inodos de ext4
  • barrier: deshabilita los write barriers.
  • noatime,nodiratime: no escribir las fechas de acceso en archivos y directorios, información poco útil en /
  • commit: permite definir la cantidad de segundos que la metadata en disco es escrita y sincronizada, 100 segundos es mucho tiempo para garantizar confiabilidad en los datos, pero aumenta drásticamente el performance.
  • inode_readahead_blks: ext4 cuenta con un algoritmo de pre-lectura (read-ahead), dicho algoritmo “pre-lee” los inodos a los lados de un inodo leído, para “optimizar” la extracción de datos, el valor por defecto es de 32 bloques, se incrementa a 64.
  • nodelalloc: ext4 ejecuta una “delayed allocation” de los bloques y solo los reserva cuando ya va a escribir a disco, esto es potencialmente peligroso combinado con data=writeback, la totalidad de los bloques que ocupan un archivo son reservados apenas la data es copiada desde userspace a la caché del dispositivo, así, cuando la metadata se esté escribiendo en el disco, ya los bloques para almacenar dicha data estarán reservados.

Sincronizando mi raíz

Para sincronizar mi partición raíz utilizo el siguiente comando rsync:

rsync -aAvPSXx --numeric-ids --exclude="/dev/*" --exclude="/proc/*" --exclude="/sys/*" --exclude="/tmp/*" --exclude="/home/*" / /ssd/

En general excluyo todo archivo que no pertenezca a la partición raíz y los puntos de montaje de sistema (/dev, /sys).

Al finalizar la sincronización, fuerzo un trim “manual” a la partición:

fstrim -v /ssd
/ssd: 3395391488 bytes were trimmed

Cambios al FSTAB

Los cambios más importantes al FSTAB (archivo: /ssd/etc/fstab) tienen que ver con el montaje “especial” de raíz, y con el montaje en RAMFS de las particiones temporales básicas del sistema:

# tmp
tmpfs /tmp        tmpfs        noatime,nosuid         0 0
tmpfs /var/run    tmpfs        nosuid,mode=0755       0 0
tmpfs /var/lock   tmpfs        noexec,nosuid,nodev    0 0

Y raíz:

UUID=970518df-7db4-44af-979c-7c9fd86a7488 / ext4 discard,noatime,nodelalloc,data=writeback,barrier=0,i_version,commit=100,inode_readahead_blks=64,errors=remount-ro 0 1

el UUID de la partición /dev/sdb1 lo obtienen fácilmente con el comando “blkid”

Actualizando GRUB

En el archivo /ssd/etc/default/grub  cambiamos el elevador a “deadline“:

GRUB_CMDLINE_LINUX=”acpi_osi=Linux acpi=ht elevator=deadline”

Un I/O scheduler, implica la forma como Linux envía los bloques de datos a los discos, en general mi equipo es una estación de trabajo, tengo bases de datos, directorios, máquinas virtuales y “deadline” es la opción más idónea, manteniendo las colas con tiempos “deadline”, para que algunas muy retrasadas “expiren”, evitando que nos quedemos sin recursos, además, en deadline, las lecturas se priorizan por sobre las escrituras, mejorando el performance de largas operaciones de lectura sobre los discos.

CFQ (el elevador por defecto en Debian), es incluso más lento que “deadline” en operaciones con bases de datos o cargas multihilos.

Este siempre es mi elevador por defecto, sin embargo, para los discos SSD hay un elevador mucho más simple, NOOP.

Con NOOP, las operaciones van sin orden (y unidas) en una única cola de escritura que es entregada al dispositivo, su ordenamiento, escritura dependerán del dispositivo.

Hay que asumir el riesgo de usar uno u otro scheduler, en mi caso uso “deadline” por lo importante de priorizar las lecturas sobre las escrituras (útil en bases de datos y directorios LDAP), sin embargo, usar CFQ permitirá a un usuario garantizar un ancho de banda más consistente para ciertas aplicaciones (ejemplo: desktops).

También el scheduler puede ser cambiado por disco, algo que veremos en el próximo apartado.

Hacemos una “jaula” para poder actualizar el GRUB desde el nuevo disco SSD (montado en /ssd):

  • Monto el actual /boot dentro de /ssd
mount /dev/sda1 /ssd/boot
  • Monto los sistemas especiales con la opción “-o bind”:
mount /dev /ssd/dev -o bind
mount /sys -o bind  /ssd/sys
mount /proc -o bind /ssd/proc

Y creo la jaula con:

chroot /ssd

Ya dentro de la jaula, la ejecución de “update-grub” causará que se use /dev/sdb1 como nuevo “root”.

update-grub

actualicen además el initramfs:

update-initramfs -t -u

Y nos salimos de la jaula.

exit

Reiniciamos el equipo.

Optimización del disco

Ahora vamos a crear un archivo especial de optimización del disco (comentado anteriormente).

archivo: /sbin/optimicedisk.sh

#!/bin/bash
# script para optimizar el acceso a disco de sistemas con noop o deadline
# autor: Jesus Lara <jesuslarag@gmail.com>
disks=( sdb )
# parameters
SCHEDULER="deadline"
QUEUEDEPTH=256
BLOCKDEV=16384
NCQ=32
for DISK in "${disks[@]}"
do
      echo "Change I/O elevator to $SCHEDULER"
      echo $SCHEDULER > /sys/block/$DISK/queue/scheduler
      echo "Optimice server disk block size to $BLOCKDEV"
      /sbin/blockdev --setra $BLOCKDEV /dev/$DISK
      echo "Set queue depth to $QUEUEDEPTH"
      /bin/echo $QUEUEDEPTH > /sys/block/$DISK/queue/nr_requests
      echo "Enabling NCQ on $DISK"
      echo $NCQ > /sys/block/$DISK/device/queue_depth
      # read ahead and sectors read by disk
      /bin/echo "8192" > /sys/block/$DISK/queue/read_ahead_kb
      /bin/echo "4096" > /sys/block/$DISK/queue/max_sectors_kb
      if [ "$SCHEDULER" == 'deadline' ]; then
          # fifo batch reduce seeks
         /bin/echo 32 > /sys/block/$DISK/queue/iosched/fifo_batch
      fi
     # enable write-caching, readahead and disable noise-reduction (performance boost)
    /sbin/hdparm -a512 -A1 -W1 /dev/$DISK
done

En este archivo hacemos varias cosas pero 3 son muy importantes:

  • definimos la cantidad de bloques que son pre-leídos en las lecturas secuenciales (read-ahead) a 16384 (blockdev –setra)
  • Hemos indicado al sistema que este disco no es rotacional (es un SSD, sin parte móviles como platos o discos que causen latencia)
  • Habilitamos NCQ (Native Command Queuing), con NCQ se garantiza una paralelización hasta el máximo permitido (31 según LIBATA) de posibles operaciones paralelas de lectura/escritura (NOTA: debe estar habilitado AHCI en el BIOS).

original

Con esta serie de características garantizamos un equilibrio entre performance y uso.

Luego, colocamos este archivo en el rc.local:

/bin/bash /sbin/optimicedisk.sh

Y lo hacemos ejecutable:

chmod +x /sbin/optimicedisk.sh

 

Es importante además, definir si el disco es o no un dispositivo rotacional, esto afectará mucho el comportamiento de NCQ:

archivo: /etc/udev/rules.d/66-ssd.rules

# system default : set deadline scheduler for rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="deadline"
# SSD specific : set noop scheduler for non-rotating disks
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"

# set a larger readahead size
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/read_ahead_kb}="2048"

Con esta regla UDEV, nos garantizamos que para todo disco detectado como no-rotacional, entonces se seleccione el scheduler noop.

NOTA: se usa el índice 66 ya que las reglas UDEV para almacenamientos persistentes se ejecutan en la regla 60 (persistent-storage.rules).

Al finalizar el archivo de reglas lo probamos con:

udevadm test --action=add /sys/block/sdb

Y veremos entre la larga lista de acciones de udevadme algo como esto:

udev_rules_apply_to_event: ATTR '/sys/devices/pci0000:00/0000:00:1f.2/host2/target2:0:0/2:0:0:0/block/sdb/queue/scheduler' writing 'noop' /etc/udev/rules.d/66-ssd.rules:5

demostrando que la regla se ha aplicado correctamente a nuestro disco SSD.

Otras consideraciones

  • Re-organizar mi disco duro para que /var (y por sobre todo /var/cache y /var/log, además de /var/spool) queden sobre el disco SATA
  • Actualizar el firmware del disco, OCZ trae un comando para hacerlo desde Linux.
  • Realizar algunos cambios adicionales en sysctl como por ejemplo:
# VM
vm.dirty_ratio = 20
vm.dirty_background_ratio = 20
vm.dirty_bytes = 67108864
vm.dirty_background_bytes = 134217728
vm.mmap_min_addr = 4096
# swapping
vm.swappiness = 0
vm.vfs_cache_pressure = 20

Que podría explicar luego.

Conclusiones

Un disco SSD es un excelente recurso para incrementar el performance, pero por sus características, su tiempo de vida es limitado (con estas características acá aplicadas, el tiempo de vida de una portátil con SSD podría llegar a los 8 años, y yo jamás he tenido más de 8 años con la misma portátil y el mismo disco!), como todo, hay que aprender a optimizarlo y sacarle el mejor provecho posible.

Happy Hacking!

 

The post Migrando Debian a un disco SSD – Optimización básica appeared first on Phenobarbital con Soda.

Domingo 16 de noviembre de 2014

Valencia Software Libre: I Jornada de Ingenieria y Arquitectura UJAP - Carabobo

Sábado 15 de noviembre de 2014

Jesus Palencia

Tor-strong un script para automatizar la instalación de tor + polipo + privoxy + dnsmasq

Según las estadísticas de mi blog los post más visitados son los relacionados con tor, es por eso que decidí crear un script que automatiza el proceso de instalación (en Debian y derivados) siguiendo el procedimiento explicado en los post anteriores.

Tal y como lo menciona el titulo este script instala tor + polipo + privoxy + dnsmasq pueden descargarlo desde aqui.

Referencias:


Tagged: dnsmasq, polipo, privoxy, script, tor

Miércoles 12 de noviembre de 2014

Carlos Colmenarez

Carlos Colmenarez
El Blog de Zero » LINUX

El Moto G (2014) es el primero en recibir Lollipop, y algo está cambiando en Android

Como ocurrió el año pasado, Motorola ha sido la primera. Algunos usuarios americanos del Moto G (2014) ya están recibiendo Android 5.0 Lollipop y la tendencia en actualizaciones parece estar cambiando en casi todas las marcas de la plataforma.

Como ya pasó con Android 4.4 Kit Kat, no han sido los Nexus los primeros dispositivos en actualizar a Android 5.0 Lollipop. El honor recae sobre Motorola y el Moto G de segunda generación, mientras que la actualización para el Moto X estaría casi lista. Según informan algunos usuarios usuarios del Moto G (2014) libre americano, ya han comenzado a recibir la actualización vía OTA, con un peso de unos 386 MB.

La actualización llega tras la noticia que conocimos hace tiempo por la cual Motorola confirmaba que toda la gama 2013 y 2014 probaría el sabor de Android 5.0 Lollipop. La velocidad en la entrega no sorprende dada la poca personalización que Motorola hace sobre el Android que Google entrega a las compañías. Sin embargo, tiene mérito que un dispositivo como el Moto E llegue a conocer Lollipop, pues en otra marca la actualización no es que se retrasara, es que directamente la empresa no se planteara su actualización, algo que ha pasado incluso en modelos de gama alta.

Los fabricantes se están tomando más en serio los plazos

En este sentido, parece que algo está cambiando. Todas las marcas han ido confirmando ya los terminales que actualizarán a Android 5.0 Lollipop, y además se están dando más prisa de lo que nos tienen acostumbradas. Por una parte tenemos una LG que esta semana ya comenzará a actualizar su G3 (manualmente ya está disponible la actualización), una Samsung cuyo TouchWiz basado en Lollipop ya hemos podido ver en vídeo en el Galaxy S4 y en Galaxy S5, por lo que tampoco debería tardar mucho en llegar a éstos y a los Note 3 y Note 4.

Quien sale peor parada de este movimiento es, sin duda, Google. Desde el día 3 de noviembre esperamos la llegada de Android 5.0 Lollipop a los Nexus 7 de 2012 y 2013, Nexus 4 y Nexus 5, y la OTA no acaba de llegar a los usuarios. Al parecer se trata de corrección de bugs, pero siendo tú quien desarrolla el software, no da muy buena imagen a la plataforma retrasarse en los que deben ser, como la propia Google afirma, los terminales ejemplares.

fuente: celularis


Lunes 10 de noviembre de 2014

Jesús Matamoros

Jesús Matamoros
Jesus Matamoros Web blog

¿Por qué es tan importante tener un sitio web?


dirección en Internet, puede dar una imagen poco seria y profesional. Cada vez más el tener un sitio Web será definitivo para seguir en carrera.  

En la actualidad  TODA  empresa, organización, no importa el tamaño,  necesita y debe tener un sitio Web.  En EEUU y en los países más avanzados de la UE está demostrado que la intensidad en la aplicación de nuevas tecnologías y la incorporación de un Sitio Web, está correlacionado de manera positiva con el incremento de las ventas, la productividad y el valor de mercado de las empresas. Además, estudiosos del E-Business consideran que las empresas que no entren en el campo de Internet en los próximos 10 años, desaparecerán!. Conozca a continuación las ventajas de tener un sitio web...

 Ventajas de tener un sitio web:
1. Alcance mundial de sus productos y servicios: a través del sitio Web Usted podrá llegar a clientes potenciales del mundo entero. Las limitaciones geográficas ya no existen, un sitio Web es como una oficina de ventas en cada lugar del planeta.

2. Competir al lado de los más grandes:
Su imagen en Internet podrá ser comparable a cualquier gran compañía de su mismo sector. Es un terreno imparcial donde el sitio web de una empresa pequeña puede ser tanto o más atractivo que el de una empresa muy grande. Por eso podrá competir justo al lado de las empresas más grandes, de igual a igual.

3. Disponible las 24horas, todos los días año: La presencia universal también se complementa con la presencia las 24 horas, los 7 días de la semana, los 365 días del año, lo que permite que aún fuera del horario de trabajo, la empresa siga produciendo y creciendo. Además de atender otras partes del planeta que por diferencias horarias sería imposible realizarlo al instante.

4. Menos Costos Operativos:
Ahorro en gastos de publicidad, reducción de teléfono y personal, de modo que cualquier información que pudiera necesitar el cliente la podrá consultar en su página Web, esto le ahorra tiempo, dinero y reduce el número de llamadas telefónicas de su negocio, locales y de larga distancia.

5. Imagen Profesional de su empresa: Actualmente las empresas respetadas en el medio tienen presencia en la Web. El no contar con una
Logo empresa desarrollo web

En iT Labs nos dedicamos a ofrecer soluciones digitales 360º, empleando las últimas tecnologías disponibles en el mercado, poniendo especial énfasis en la funcionalidad y el posicionamiento y estrategia de marketing, permitiéndole lograr presencia en Internet. De esta manera Usted y su empresa podrán competir estratégicamente, utilizando nuestros productos como una herramienta de marketing, publicidad y hasta gestión empresarial.


Miguel Ángel Useche

Miguel Ángel Useche
El weblog de Skatox » Planetas

Cómo empecé a usar Firefox hace una década

Ayer 9 de noviembre, se cumplieron 10 años del lanzamiento de la versión 1.0 de Firefox, el navegador que sigo usando actualmente por diversas razones que les comentaré en esta entrada. Aunque recuerdo utilizar Netscape cuando iba a los populares cybercafes (pues en los 90s no era común tener Internet en el hogar) mi salida de Internet Explorer (que por venir instalado con Windows era mi predeterminado) fue como a finales del 2002 cuando empecé a jugar con páginas de seguridad informática y en uno de los retos me pedía falsificar el navegador, averiguando instalé K-meleon que se convirtió en mi navegador por defecto por incluir pestañas. Luego me enteré que el navegador estaba basado en otro llamado Mozilla Suite y ahí empezó todo.
Cuando me enteré del desarrollo de Firefox, recuerdo que no me gustó por ser un navegador con pocas funcionalidades respecto a Mozilla Suite (me encataba la idea de tener un cliente IRC y de correo en el navegador) y lo ignoré por completo hasta que instalé la primera versión de Ubuntu que venía con Firefox 0.93. En ese entonces, al ser una numeración menor a 1.0, pensé que el navegador era una beta y no lo probé hasta su lanzamiento; ese día recuerdo bajar un versión binaria, pues no había paquete oficial para Ubuntu 4.10 y al probarlo me gustó por su rapidez. De ahí seguí utilizando versión por versión, creo que la 1.5 no la usé por gran tiempo debido a problemas de video en mi equipo y utilicé, pero luego volví con la versión 2.0.

Haciendo una retrospectiva de las versiones del navegador, es impresionante como ha cambiado la web en 10 años. Cuando salió Firefox, Internet Explorer controlaba el mercado y casi todas las páginas se hicieron para funcionar en ella, además apenas estaba surgiendo la primeras aplicaciones web, Javascript no era tan importante, era necesario utilizar plugins de terceros para ver animaciones y videos en la web, pocos sitios usaban llamadas AJAX, entre otros. Ya hoy en día gracias a Firefox, tenemos la posibilidad de escoger otros navegadores como Chrome (Firefox permitió abrir el paso a otros navegadores), brindar mayor sentido a las estadarizaciones en la web, implementar futuras tecnologías, ejecutar código JS a velocidades cercanas a código nativo, por nombrar algunas cosas. Ademas, Firefox se ha convertido en el navegador mas rápido (a la fecha de publicación de esta entrada), sirve de base para Firefox OS, tiene una versión para Android, se enfoca en los intereses de los usuarios y no de una organización, te protege tu información y respeta tu privacidad, puedes sincronizar de forma privada y segura la información de tu navegador entre dispositivos, está desarrollado por gente de distintas partes del mundo y de forma totalmente abierta, entre otros. Por estas razones y más, les recomiendo utilizar este navegador, no solo por su gran calidad desde el punto de vista técnico, sino también porque al usarlo apoyas a la web abierta.

P.d: Puede estar un poco extraña la redacción del post pero lo redacté con mucho sueño luego de organizar y realizar el evento.

Domingo 02 de noviembre de 2014

Ramon Marquez

Ramon Marquez
Libuntu » Linux

El 14 de noviembre estará disponible “This War Of Mine”, el juego de guerra que necesitábamos.

El próximo 14 de noviembre, la desarrolladora de videojuegos polaca 11 bit Studios lanza al mercado su juego “This War Of Mine”, el juego de guerra que necesitábamos. La guerra es un tema constante en los videojuegos, no importa si te toca ser el dirigente de una nación en un juego de “Grand Strategy”, comandante… Read More »
Jorge Ortega

Jorge Ortega
Joenco

Como hacer que Espeak reconozca las voces de mbrola

Revisando en internet como agregar las voces de mbrola en “Gespeaker“, me encontré con este articulo: “Gespeaker. Texto a voz” donde explica que hacer para que espeak reconozca las voces de mbrola y es lo que les voy a comentar para que ustedes también las utilicen!!

 

Lo que vamos hacer es instalar mbrola y las voces en español, esto por si aun no lo han hecho:

1. Abrimos un terminal/consola.

2. Entramos como superusuario (root, escribiendo:

# su

3. Escribimos la contraseña de administrador:

# la -contraseña-de-root

4. Instalamos mbrola y las voces:

# aptitude install mbrola mbrola-es1 mbrola-es2 mbrola-mx2 mbrola-vz1

5 Creamos una carpeta llamada “ves” en /usr/lib/i386-linux-gnu/espeak-data/voices/:

# mkdir /usr/lib/i386-linux-gnu/espeak-data/voices/ves

6. Copiamos los archivos mb-es1, mb-es2, mb-mx2 y mb-vz1 que se encuentra en /usr/lib/i386-linux-gnu/espeak-data/voices/mb/ en la carpeta creada:

# cp /usr/lib/i386-linux-gnu/espeak-data/voices/mb/mb-es* /usr/lib/i386-linux-gnu/espeak-data/voices/vz1/

# cp /usr/lib/i386-linux-gnu/espeak-data/voices/mb/mb-mx2 /usr/lib/i386-linux-gnu/espeak-data/voices/vz1/

# cp /usr/lib/i386-linux-gnu/espeak-data/voices/mb/mb-vz1 /usr/lib/i386-linux-gnu/espeak-data/voices/vz1/

Listo, eso es todo ya podremos utilizar las voces de mbrola con espeak.!

 

Lo mejor es que podremos usar las nuevas voces con Gespeaker y el lector de pantalla orca, lo malo (no todo es perfecto), cuando se usa con el lector de pantalla no reproduce algunas cosas.

 

Es de destacar que se puede utilizar la voz venezolana sin ningún problema para reproducir cualquier texto utilizando “Gespeaker”.!!

 

Nota: En el articulo “Instalando otras voces para el lector de pantalla orca” se explica como hacer que se reconozca mbrola en las opciones.

 

Saludos a todos y para cualquier pregunta, comentario o sugerencia lo pueden hacer en los comentarios.


Viernes 31 de octubre de 2014

Ramon Marquez

Ramon Marquez
Libuntu » Linux

La rama 3.16 del kernel Linux tendrá soporte extendido

A través de la lista de correo de Linux se ha anunciado el soporte extendido para la rama 3.16 por parte del equipo de desarrollo de Ubuntu y de Debian. El soporte extendido de Linux 3.16 ha entrado en vigencia, la particularidad de todo esto es que el soporte estará a cargo de terceras personas… Read More »

Jueves 30 de octubre de 2014

Ramon Marquez

Ramon Marquez
Libuntu » Linux

Se lanzan nuevas versiones de actualización del kernel Linux

Greg Kroah-Hartman ha anunciado a través de la lista de correo de Linux, el lanzamiento de varias versiones de actualización para algunas ramas del kernel Linux trayendo consigo varias mejoras, actualizaciones de drivers y numerosos arreglos de errores. Las versiones 3.17.2, 3.16.7, 3.14.23 y 3.10.59 del kernel Linux han sido lanzadas el día de hoy,… Read More »

Domingo 26 de octubre de 2014

Jorge Ortega

Jorge Ortega
Joenco

Hostinger: un sitio de hosting web accesible, gratuito y sin publicidad

Hostinger: un sitio de hosting web accesible, gratuito y sin publicidad.


Sábado 18 de octubre de 2014

Instalar Drivers Privados de AMD Radeon (fglrx) Debian Wheezy

Recientemente adquirí una humilde AMD Radeon R9 270, y quise instalar los drivers propietarios (fglrx) para poder jugar UrT como dios manda.

Añadir los repositorios backports para Debian Wheezy, en el archivo /etc/apt/sources.lst
# Backports Debian Wheezy
deb http://http.debian.net/debian/ wheezy-backports main contrib non-free

Actualizar la lista de paquetes
$ aptitude update && aptitude update

Instalar el driver fglrx
$ aptitude -r -t wheezy-backports install fglrx-driver fglrx-control

Esto creará el archivo xorg.conf usando el módulo fglrx
$ aticonfig –initial

Agregar el driver libre “radeon” a la lista negra, modificar el archivo: /etc/modprobe.d/radeon-kms.conf; si tienes el archivo, de no tenerlo lo creas y agregas:
blacklist radeon
options radeon modeset=1

Reiniciar el equipo y listo!

Para probar si efectivamente el driver esta funcionando, utilizar las siguientes utilidades:

$ fglrxinfo

La salida debe ser algo como esto:
display: :0.0 screen: 0
OpenGL vendor string: Advanced Micro Devices, Inc.
OpenGL renderer string: AMD Radeon R9 200 Series
OpenGL version string: 4.3.12618 Compatibility Profile Context 8.982.13

$ glxinfo | grep render
La salida debe ser: direct rendering: Yes

$ glxgears
La salida debe ser una ventana con 3 engranajes (colores azul, rojo, verde) y un average FPS cada 5 segundos

$ fgl_glxgears
La salida debe ser una ventana con un cubo, en cada cara hay 3 engranajes (colores azul, rojo, verde; como en la salida anterior) y un average FPS cada 5 segundos

Los drivers disponibles en wheezy-backports son los AMD Catalyst 13.12, que tienen un buen rendimiento en linux incluso mejor que la serie 14.xx, sobre todo si se desea probar la minería Litecoin.

Saludos !

Viernes 17 de octubre de 2014

Vulnerabilidad crítica “Shellshock” afecta a Linux y OS X

Está Escrito:
No lo que entra en la boca contamina al hombre; mas lo que sale de la boca, esto contamina al hombre. (Mateo 15:11)
Tomado de: DiarioTI
Descuido en el diseño de la herramienta 'bash' - intérprete de la línea de comandos de Unix - permite en teoría ejecutar código a distancia y así tomar el control de sistemas. Shellshock ha impactado aproximadamente a medio millón de servidores web y dispositivos.

Una vulnerabilidad crítica recién descubierta llamada Shellshock, ha impactado aproximadamente a medio millón de servidores web, así como dispositivos conectados a Internet, incluyendo teléfonos móviles, routers y dispositivos médicos; de acuerdo con los expertos de defensas amenazas de Trend Micro. La empresa destaca que Shellshock, al estar relacionado con Linux, puede también afectar a las plataformas PC y Apple.
Shellshock es una vulnerabilidad crítica, que Trend Micro describe como “una plaga”. Dicha amenaza, al ser explotada, permite el acceso a los sistemas basados ​​en Linux a través de sus líneas de comando.
Considerando que estos sistemas constituyen aproximadamente el 51% de los servidores web en el mundo, la capacidad de penetración es elevada y los ataques podrían aumentar a un ritmo muy rápido.
“La reciente vulnerabilidad Heartbleed es de naturaleza similar a Shellshock, pero Heartbleed solo queda eclipsada por la extensión y alcance de esta nueva vulnerabilidad”, escribe Trend Micro.
Debido a la naturaleza y alcance de Shellshock, la empresa sugiere considerar lo siguiente:
- Usuario final: Estar atento a los nuevos parches de seguridad e implementarlos inmediatamente.
- Administrador de TI: Si cuentan con el sistema Linux, se recomienda deshabilitar los scripts o las secuencias de comandos BASH inmediatamente.
- Operador de sitio Web: Si el BASH está en sus scripts, parche lo antes posible, o modifique sus scripts para no utilizar BASH.
· Clientes que cuentan con servicios de hosting o de terceros: Pregunte a su proveedor que están haciendo para remediar y aplicar parches.
Trend Micro ofrece información actualizada sobre Shellshock” en su blog de seguridad.

Jueves 16 de octubre de 2014

Jorge Ortega

Jorge Ortega
Joenco

Script para agregar atajos de teclado en Gnome-shell

Una de las cosas que me gusta hacer cuando instalo por primera vez un equipo, es poder tener atajos de teclado o combinaciones de teclas para abrir mis aplicaciones preferidas como por ejemplo el Terminal/Consola, el editor de texto Gedit, el editor de documentos, el Pidgin, entre otras.

Gracias a que estoy suscrito en la lista de “tiflo-linux“, preguntando que archivos debía modificar para crear un script que me permitiera agregar los atajos sin necesidad de hacer eso gráficamente, el compañero “Manuel Cortéz” me comentó que en la pagina “http://community.linuxmint.com/tutorial/view/1171&#8243; explicaban como hacerlo, que me ayudo bastante para entender como se agrega los atajos por consola.

Haciendo algunas pruebas y ensayos, logre tener un script que me permite agregar atajos de teclado de mis aplicaciones favoritas y el cual puedes descargar sin problema: “script para agregar atajos en Gnome-shell“, para ejecutar debes:

1. Abrir un Terminal/Consola

2. Escribir:

$ python agregaratajos.py

      1. Listo!!, ya tienes los atajos.

Estas son las aplicaciones y sus atajos:

Gedit ctrl+alt+e

Terminal ctrl+alt+t

Writer ctrl+alt+w

Calc ctrl+alt+c

Pidgin ctrl+alt+p

Orca ctrl+alt+o

Carpeta personal ctrl+alt+h

Skype ctrl+alt+s

Gespeaker ctrl+alt+g

Navegador web ctrl+alt+n

Este script lo probé en Debian y Canaima4.0 pero debería funcionar también en Ubuntu y derivados, es de destacar que solo estoy identificando los navegadores “Iceweasel”, “Firefox” y “Cunaguaro”.

Si tienen alguna pregunta, duda o sugerencia sobre que falta en el script, me lo hacen saber en los comentarios.

Saludos a todos y ya sabes, si te ha gustado compártelo!!


Miércoles 15 de octubre de 2014

Replicación con OpenLDAP

Replicación con OpenLDAP

Continuando con las entradas referentes a OpenLDAP, esta vez nos orientamos hacia la replicación.

A diferencia de otros servicios de replicación, dónde se habla de “Maestro” y “Esclavo”, en OpenLDAP se habla de “Provedores” y “Consumidores” (Consumers-Providers), esto es debido a que un mismo servidor puede proveer datos a un DSA y además consumir datos de otro DSA, permitiendo configuraciones distribuidas de múltiples ramas y árboles.

Replicación con OpenLDAP

Replicación con OpenLDAP

Existen varias formas de replicación:

  • N-Way Multi-Master: todos los servidores son maestros y todos aceptan cambios y los replican al resto de los DSA.
  • Mirror Mode: es una replicación maestro-maestro entre dos nodos, donde cada DSA replica al próximo DSA los cambios, Mirror-mode es un N-WAY con N=2.
  • Syncrepl: En general, la forma básica de replicación Syncrepl es en modo Maestro-Esclavo, donde una entrada modificada es replicada a cada esclavo que “consuma” los cambios del servidor maestro.
  • Delta Syncrepl: En Delta Sync, se crea un diferencial de cambios (Delta-change) y solamente los atributos modificados en la entrada son replicados, mejorando eficientemente la transferencia de la replicación.

Atributos de la Replicación

olcServerID: es la lista de identificadores únicos de cada server, cada DSA debe tener un ID único y ser el mismo en todos los nodos del cluster de servidores.

RID: el ID de la replicación, es único por cada vía de replicación en cada server

Para replicación openLDAP se utiliza SyncProv, un proveedor de sincronía entre diversos servidores openLDAP.

Configurando la Replicación

Vamos a configurar la réplica sencilla (Mirror-Mode) entre 2 servidores, ldap1 y ldap2.

La definición de ámbos debe existir en los DNS o al menos, en el /etc/hosts:

172.16.30.10 ldap1.devel.com.ve ldap1

172.16.30.11 ldap2.devel.com.ve ldap2

Cargamos la identificación de ámbos servidores (olcServerID)

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: cn=config
changeType: modify
replace: olcServerID
olcServerID: 1 ldap://ldap1.devel.com.ve
olcServerID: 2 ldap://ldap2.devel.com.ve
EOF

Y modificamos los límites, para que el usuario que realizará la réplica no tenga problemas de timeouts o tamaño de entradas:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcLimits
olcLimits: dn.exact="cn=admin,dc=devel,dc=com,dc=ve" time.soft=unlimited 
  time.hard=unlimited size.soft=unlimited size.hard=unlimited
-
add: olcDbIndex
olcDbIndex: entryUUID,entryCSN  eq
EOF

Además indexamos los atributos que contienen el timestamp de las entradas y su UUID.

Habilitamos el Overlay SyncProv para el Backend del arbol y para cn=config:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcOverlay=syncprov,olcDatabase={2}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 20 10
olcSpSessionlog: 500
olcSpNoPresent: TRUE
EOF
ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcOverlay=syncprov,olcDatabase={0}config,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: syncprov
olcSpCheckpoint: 20 10
olcSpSessionlog: 500
olcSpNoPresent: TRUE
EOF

Ahora, habilitamos el RID entre uno y otro servidor, contra cn=config y el backend del árbol primario:

En el servidor1 (ldap1) aplicamos los LDIF para cargar réplica en cn=config y en el árbol primario:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://ldap2.devel.com.ve binddn="cn=admin,cn=config" bindmethod=simple 
  credentials=123456 searchbase="cn=config" type=refreshAndPersist retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
EOF
ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=002 provider=ldap://ldap2.devel.com.ve binddn="cn=admin,dc=devel,dc=com,dc=ve" bindmethod=simple
  credentials=123456 searchbase="dc=devel,dc=com,dc=ve" type=refreshAndPersist  interval=00:00:00:10 retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
EOF

Y en el servidor2:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=001 provider=ldap://ldap1.devel.com.ve binddn="cn=admin,cn=config" bindmethod=simple 
  credentials=123456 searchbase="cn=config" type=refreshAndPersist retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
EOF

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: olcDatabase={2}mdb,cn=config
changetype: modify
add: olcSyncRepl
olcSyncRepl: rid=002 provider=ldap://ldap1 binddn="cn=admin,dc=devel,dc=com,dc=ve" bindmethod=simple
  credentials=123456 searchbase="dc=devel,dc=com,dc=ve" type=refreshAndPersist  interval=00:00:00:10 retry="5 5 300 5" timeout=3
-
add: olcMirrorMode
olcMirrorMode: TRUE
EOF

Reiniciamos en ámbos servidores:

service slapd restart

Probando la replicación

Podemos verificar la replicación, creando una entrada en ldap1 y verificando que dicha entrada aparece en ldap2:

en ldap1:

ldapadd -H ldapi:/// -x -D cn=admin,dc=devel,dc=com,dc=ve -W << EOF
dn: ou=services,dc=devel,dc=com,dc=ve
objectClass: top
objectClass: organizationalUnit
ou: services
description: Services and Apps
EOF

En ldap2:

ldapsearch -H ldaps://localhost -b dc=devel,dc=com,dc=ve -D cn=admin,dc=devel,dc=com,dc=ve -W -s sub '(ou=services)' -x -LLL
Enter LDAP Password: 
dn: ou=services,dc=devel,dc=com,dc=ve
objectClass: top
objectClass: organizationalUnit
ou: services
description: Services and Apps

Entonces hemos verificado que nuestra sencilla replicación Mirror-Mode (maestro-maestro de 2 nodos) está operativa.

 

Ya sabes!, si te gustan estos artículos, apoya a que este sitio web siga operativo, ¡dona!, o haz click en alguna publicidad de este blog.


The post Replicación con OpenLDAP appeared first on Phenobarbital con Soda.

OpenLDAP TLS/SSL : Configuración básica y aseguramiento

Seguridad OpenLDAP TLS/SSL

Una de las características más imprescindibles de todo directorio que se configure, es el mantener el tráfico seguro, en anterior entrega aprendimos a proteger nuestras contraseñas, ahora aprenderemos a proteger el tráfico mismo del servidor OpenLDAP usando SSL y TLS.

Continuando con la saga de artículos sobre openLDAP, acá el dedicado a seguridad TLS/SSL.

 

SSL

SSL (Secure Socket Layer) permite establecer un enlace cifrado entre el cliente LDAP y el Servidor OpenLDAP, SSL es un estándar y se implementa en Linux mediante openSSL.

SSL requiere un certificado de llave pública, dicho certificado público se le otorga a los clientes a través de la conexión y valida que el servidor al que nos estamos conectando es realmente el servidor al que deseamos conectarnos; luego que ambas partes admiten la conexión, esta se realiza por un canal seguro, cifrado.

Para trabajar con certificados auto-firmados (aquel que es generado por el propio servidor) en Debian, este proporciona una herramienta práctica de gestión/generación de certificados auto-firmados.

Instalación

Instalamos la herramienta de gestión de certificados de Debian

apt-get install openssl ssl-cert ca-certificates

Generando unos certificados genéricos auto-firmados:

/usr/sbin/make-ssl-cert generate-default-snakeoil --force-overwrite

Dicho certificado genérico auto-firmado se encuentra en /etc/ssl/certs.

Cambiamos el grupo al directorio ssl:

chgrp ssl-cert /etc/ssl/ -R

Y agregamos al usuario openLDAP al grupo “ssl-cert” para poder leer los certificados (y no tener que copiarlos a otro directorio):

usermod -G ssl-cert,openldap openldap

Verificando que el usuario ya se encuentra en el grupo:

id openldap

uid=114(openldap) gid=104(openldap) groups=104(openldap),105(ssl-cert)

Reiniciamos el servicio:

service slapd restart

Y hacemos uso de dicho certificado:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: cn=config
changetype:modify
replace: olcLocalSSF
olcLocalSSF: 71
-
replace: olcTLSCACertificatePath
olcTLSCACertificatePath: /etc/ssl/certs
-
replace: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/ssl/certs/cacert.org.pem
-
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ssl/certs/ssl-cert-snakeoil.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ssl/private/ssl-cert-snakeoil.key
-
replace: olcTLSVerifyClient
olcTLSVerifyClient: never
-
replace: olcTLSCRLCheck
olcTLSCRLCheck: none
EOF

Nota: con el atributo olcLocalSSF definimos el nivel de seguridad que admitirá el servidor, SSF significa “Security Strength Factor” donde:

0 = no seguridad requerida

1 = chequeo de integridad exclusivamente

71 = implica que cualquier cifrado es “opcional” (ej: permite acceso vía ldapi socket el cual no es cifrado).

128 = fuerza el uso de conexiones con algún tipo de cifrado

Habilitamos SSL como modo de conexión en /etc/default/slapd

archivo: /etc/default/slapd

sed -i "s/SLAPD_SERVICES=\"ldap:\/\/\/ ldapi:\/\/\/\"/SLAPD_SERVICES=\"ldap:\/\/\/ ldapi:\/\/\/ ldaps:\/\/\/\"/g" /etc/default/slapd

Reiniciamos el servicio:

service slapd restart

Y verificamos que está escuchando por el puerto 636:

lsof -i tcp:636
COMMAND  PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
slapd   5776 openldap   11u  IPv4   8045      0t0  TCP *:ldaps (LISTEN)
slapd   5776 openldap   12u  IPv6   8046      0t0  TCP *:ldaps (LISTEN)

Adicionalmente, podemos verificar la conexión SSL mediante openssl:

openssl s_client -connect localhost:636 -showcerts
New, TLSv1/SSLv3, Cipher is DES-CBC3-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DES-CBC3-SHA
    Session-ID: 9C0674ED1BEEE9D790F91CDD25D67C60B41E4F2B9AA9D47985E1F4CB6D3112A0
    Session-ID-ctx: 
    Master-Key: 29FC9B902F61C6F5D843C60923BE4B4B71E5252930F0093196B8B2199728C1CD9E05B7278B98C5E7CC584F3D5AA9849F
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1412140120
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---

La conexión nos ha retornado un certificado auto-firmado (self-signed cert)

Configuramos el archivo ldap.conf para utilizar el certificado CA actual:

archivo: /etc/ldap/ldap.conf
BASE dc=devel,dc=com,dc=ve
URI ldaps://localhost ldap://localhost
SIZELIMIT 12
TIMELIMIT 15
DEREF never
# TLS-SSL
TLS_CACERT /etc/ssl/certs/cacert.org.pem
TLS_REQCERT never

TLS_REQCERT define si un certificado es solicitado o no por el servidor, para conexiones donde se especificará exclusivamente conexiones TLS/SSL se debe colocar en modo “demand”.

Ya podemos verificar la conexión SSL usando ldapsearch:

ldapsearch -H ldaps://localhost -b dc=devel,dc=com,dc=ve -D cn=admin,dc=devel,dc=com,dc=ve -W -s sub '(cn=admin)' -x -LLL

TLS

TLS o “Transport Layer Security” es la evolución de SSL y es de hecho, el modo en el que openLDAP cifra sus conexiones por defecto, aunque obviamente comparte características y atributos de configuración con SSL.

Instalamos en Debian:

apt-get install gnutls-bin

Incorporamos los cifrados TLS con los que cifrará las conexiones nuestro servidor OpenLDAP:

ldapadd -H ldapi:/// -Y EXTERNAL -Q << EOF
dn: cn=config
changetype: modify
replace: olcLocalSSF
olcLocalSSF: 71
-
replace: olcSecurity
olcSecurity: update_ssf=128 simple_bind=128
-
replace: olcTLSCipherSuite
olcTLSCipherSuite: +RSA:+AES-256-CBC:+SHA1
EOF

TLSCipherSuite define la lista de cifrados en las cuales el servidor SLAPD negociará las conexiones.
Usaremos cifrado RSA o AES de 256bits con MAC SHA1, es el modo más compatible de cifrado, soportado por la mayoría de las librerías LDAP que soporten TLS1 o SSL3.
Nota: para mostrar la lista de cifrados compatibles se debe ejecutar:

gnutls-cli -l

Que retornará algo como esto:

Cipher suites:
TLS_ANON_DH_ARCFOUR_MD5 0x00, 0x18 SSL3.0
TLS_ANON_DH_3DES_EDE_CBC_SHA1 0x00, 0x1b SSL3.0
TLS_ANON_DH_AES_128_CBC_SHA1 0x00, 0x34 SSL3.0
TLS_ANON_DH_AES_256_CBC_SHA1 0x00, 0x3a SSL3.0
TLS_ANON_DH_CAMELLIA_128_CBC_SHA1 0x00, 0x46 TLS1.0
TLS_ANON_DH_CAMELLIA_256_CBC_SHA1 0x00, 0x89 TLS1.0
TLS_ANON_DH_AES_128_CBC_SHA256 0x00, 0x6c TLS1.2
TLS_ANON_DH_AES_256_CBC_SHA256 0x00, 0x6d TLS1.2
TLS_PSK_SHA_ARCFOUR_SHA1 0x00, 0x8a TLS1.0
TLS_RSA_AES_128_CBC_SHA256                            0x00, 0x3c    TLS1.2
TLS_RSA_AES_256_CBC_SHA256                            0x00, 0x3d    TLS1.2
Certificate types: CTYPE-X.509, CTYPE-OPENPGP
Protocols: VERS-SSL3.0, VERS-TLS1.0, VERS-TLS1.1, VERS-TLS1.2
Ciphers: AES-256-CBC, AES-128-CBC, 3DES-CBC, DES-CBC, ARCFOUR-128, ARCFOUR-40, RC2-40, CAMELLIA-256-CBC, CAMELLIA-128-CBC, NULL
MACs: SHA1, MD5, SHA256, SHA384, SHA512, MD2, RIPEMD160, MAC-NULL

Luego de incorporado el cifrado, reiniciamos:

service slapd restart

Y verificamos que podemos  iniciar una negociación TLS:

ldapsearch -x -H ldap://localhost -b dc=devel,dc=com,dc=ve -D cn=admin,dc=devel,dc=com,dc=ve -W -s sub '(cn=admin)' -LLL -ZZ

-ZZ inicia una negociación TLS sobre el puerto 389, forzando una respuesta  correcta.

The post OpenLDAP TLS/SSL : Configuración básica y aseguramiento appeared first on Phenobarbital con Soda.

Martes 14 de octubre de 2014

Respaldo y recuperación completo de GitLab con Postgresql

GitLab and Posgresql

GitLab tiene como la posibilidad de usar Postgresql como su motor de base de datos (a parte de MySQL) y todo viene ya listo para incluso hacer respaldos de su base de datos y sus repositorios Git haciendo uso de un script Ruby (un rake).  Esta es la forma recomendada ya que permite recuperar todo garantizando que no hay transacciones pendientes a nivel de base de datos ni de repositorios Git.

El  problema

En la documentación explican el detalle de cómo hacer un respaldo y restauración  manual, pero al momento de hacer la restauración esta falla porque al intentar insertar registros existentes estos generan conflictos como este:

ALTER SEQUENCE
psql:/home/git/gitlab/tmp/backups/db/database.sql:812: ERROR: relation "users" already exists

La solución

Se debe forzar el respaldo de pogresql para que primero borre las tablas para luego crearlas e insertar los registros en la restauración. Esto se consigue con la opción –clean o -c  de la orden pg_dump. Esta opción se debe editar en script ruby que realiza el respaldo, que por omisión es /home/git/gitlab/lib/backup/database.rb. En este archivo se debe ubicar esta porción del código y sustituir la línea en negrilla mostrada a continuación:

require 'yaml'
module Backup
 class Database
 attr_reader :config, :db_dir
def initialize
 @config = YAML.load_file(File.join(Rails.root,'config','database.yml'))[Rails.env]
 @db_dir = File.join(Gitlab.config.backup.path, 'db')
 FileUtils.mkdir_p(@db_dir) unless Dir.exists?(@db_dir)
 end
def dump
 success = case config["adapter"]
 when /^mysql/ then
 print "Dumping MySQL database #{config['database']} ... "
 system('mysqldump', *mysql_args, config['database'], out: db_file_name)
 when "postgresql" then
 print "Dumping PostgreSQL database #{config['database']} ... "
 pg_env
 system('pg_dump', config['database'], out: db_file_name)
 end
 report_success(success)
 end

Esta línea debe sustituirse por esta otra:

system('pg_dump', config['database'], '-c', out: db_file_name)

Aquí puede verse que la opción -c es pasada como argumento a la orden pg_dump. Esto hará que se incluyan todos los DROPS necesarios en el archivo .sql generado para el respaldo de GitLab

Actualización

En GitLab 7.4 este problema fue resullto con esto https://gitlab.com/gitlab-org/gitlab-ce/commit/77b57c114be6b1fa02538c35066ccc363bfe68e6 [Gracias Sytse Sijbrandij]

.

Sábado 11 de octubre de 2014

Valencia Software Libre: LXDE el escritorio liviano por excelencia

Viernes 10 de octubre de 2014

Probando una Epson multifuncional L210

Probando una Epson multifuncional

La impresora epson multifuncional L210 llega con tecnología innovadora de tanques de tinta, para imprimir miles, ahorrando miles. Con la tinta incluida, imprime* hasta 4,000 páginas en negro y 6,500 páginas a color, a un bajo costo de pocos centavos por página. Imprime, copia y escanea con gran calidad y facilidad. La L210 revoluciona la impresión en pequeñas oficinas y hogares -ideal para documentos, copias, reportes y fotos. Configure la impresora multifuncional en minutos y comience a producir impresiones de alta calidad. Obtendrá fotos y documentos nítidos y llenos de vida de manera rápida. Además, no es necesario esperar para manipular sus impresiones gracias a la tinta de secado instantáneo. También puede realizar copias a color. O bien, escanee y guarde recetas, informes escolares y documentos importantes; todo con el software que se incluye.

¿Qué hay en la caja?

  • La impresora.
  • 1 botella de tinta negra y 3 botellas de tinta a color (cian, magenta y amarilla) de 70ml cada una.
  • Cable de Alimentación.
  • Cable USB.
  • Guía rápida de instalación.
  • CD con drivers, manuales, software OCR y para edición de fotos.

Compatibilidad

  • Windows® 7
  • Windows Vista®
  • Windows XP
  • Windows XP Professional x64
  • Mac OS® X, 10.5.8, 10.6.x, 10.7.x, 10.8.x

Para saber mas de las caracteristicas, clic aqui.

Como instalarla en linux

La instalacion es totalmente sencilla, solo debemos ir a esta pagina http://download.ebz.epson.net/dsc/search/01/search/searchModule

Donde nos pregunta: “Enter product name” debemos colocar: “L210” que corresponde el nombre del nuestra impresora.

Selecionamos nuestro sistema operativo, en este caso, Linux

El resultado de la busqueda nos va a dar dos opciones de descarga:

  • Printer Driver
  • Scanner Driver

Bajamos esos paquetes, y listo, ya tenemos funcionando nuestra impresora epson sin problemas en nuestro equipo.

Nota

Recuerden seguir las instrucciones de recarga de los cartuchos. Es importante seguirlas al pie de la letra ;)

Miguel Ángel Useche

Miguel Ángel Useche
El weblog de Skatox » Planetas

La evolución de la web

Llevo muchos años haciendo desarrollo web, aproximadamente en 1999 hice mi primera página web en el extinto Geocities y de allí hice páginas por entretenimiento hasta que en el 2003, con esta página (antes de ser un blog) y otra de skate he estado involucrando en el mundo web.

Desde entonces ha habido muchos cambios en la web, por una parte, antes solo existía un navegador como tal pues Internet Explorer ocupaba como el 95% de la cuota y pocas personas usaban Netscape, limitando a los desarrolladores a solo crear cosas disponibles en esta aplicación que Microsoft había abandonado. Esto ocasionó el despliegue de complementos de terceros como Flash y Java, que traían a la web mayor interacción, animaciones a cambio de menor seguridad y lentitud. Pero al hacer un sitio con esas tecnologías, estabas seguro que funcionaba en cualquier computadora y que eventualmente tus lectores iban a sufrir vulnerabilidades de seguridad.

Por otra parte, en el año 2004 salió el navegador Mozilla Firefox que logró brindar una alternativa a los usuarios de la web y abrir la posibilidad de nuevos navegadores como Google Chrome que salió en 2008, para así destronar a Internet Explorer y fomentar una sana competencia por ganar usuarios a través de calidad, permitiendo el avance de tecnologías abiertas y el impulso de HTML5/CSS3. Con estas alternativas, los programadores y diseñadores tuvieron que adaptarse a los nuevos tiempos y actualizar o crear sus páginas para funcionar en cada navegador del mercado, pues dar soporte a uno solo no es opción, porque olvidas a sector importante de usuarios de Internet.

Con el lanzamiento de dispositivos móviles ahora la web estaba disponible en todas partes, desde cualquier lado puedes acceder a ella y fuera de tu computadora personal. Creando un nuevo reto pues una página no solo debía funcionar bien en todos los navegadores sino también en múltiples tamaños de pantalla y resoluciones, aumentando un poco el trabajo de los desarrolladores pero creando sitios dinámicos que funcionan en cualquier tamaño de pantalla.

Podría decirse que la evolución de la web siempre pone retos a los desarrolles y a quienes ejercen el diseño de sitios web, pero a su vez, permite a los usuarios disfrutar de una mejor plataforma, cada vez con mas posibilidades audiovisuales de forma nativa, tener videojuegos 2D y 3D en el navegador, contar con sistemas operativos como Chrome OS y Firefox OS que ejecutan aplicaciones web y muchas cosas mas por venir. Demostrando que tenemos a la web por mucho tiempo y seguirá siendo el principal medio de comunicación en el mundo.

Domingo 05 de octubre de 2014

Script php para chequear y notificar disponibilidad de servidores en SoYouStart

Miércoles 01 de octubre de 2014

Cómo activar la interfaz Web de qBittorrent

Si deseas controlar to servidor qBittorrent usando la interfaz web, sigue los siguientes pasos:

  1. En la barra de menú, ve a Tools > Options qBittorrent WEB UI
  2. En la próxima ventana, selecciona la opción Web UI
  3. Marca la opción Enable the Web User Interface (Remote control)
  4. Selecciona un puerto (Por omisión 8080)
  5. Configura el nombre de usuario y contraseña (Por omisión username: admin / password: adminadmin) WEB UI
  6. Haz clic en Ok para guardar las configuraciones.

Ahora podrás acceder a tu servidor desde un navegador si colocas la dirección IP y puerto de tu servidor qBittorrent, ejemplo: 192.168.1.100:8080 como se muestra a continuación: qBittorrent Web UI También puedes acceder desde tu dispositivo Android si instalas qBittorrent Client o qBittorrent Client ProqBitttoren Client Pro

Inkscape: Donde cada elemento es una capa

¿Te has preguntado en que se diferencia Inkscape de GIMP? Una de las principales razones por las cuales Inkscape es más utilizada para elaborar publicidad, es porque trata a cada elemento como una capa individual, esto permite que al elaborar un arte central, puedas simplemente reorganizar los elementos que lo componen para realizar un nuevo diseño, por lo tienes que olvídate de borrar y parchar nada.

En Gimp, si dibujamos varias figuras y no colocamos cada una en una capa, cuando queramos separarlas, no podremos, ya que todos los componentes que hicimos forman parte de una misma capa, en cambio, si realizamos las mismas figuras en inkscape, la diferencia es que podremos separarlas y trabajar con ellas como elementos individuales ya que cada una de ellas se comporta como una capa.

Por ejemplo, el diseño de esta web fue hecho con inkscape, así que dale un vistazo, deja tu comentario y no olvides suscribirte a mi canal de youtube y a este portal para seguir aprendiendo de forma fácil y rápida!

Y si te gusta mi contenido, no te olvides de votar por este blog como Mejor Blog de Software Libre, solo dale click al botón amarillo que dice “Votar” y confirma tu email! :D

flattr this!

Sábado 27 de septiembre de 2014

Realizar un RMA (Return Merchandise Authorization) desde Venezuela

Hola, de nuevo por acá.

Por allá por el 2012 compré un kit de memoria RAM DDR3 de 2x4Gb PC12800 en amazon. Por razones obvias, no fue hasta 2013 en que terminé de armar mi máquina (la descripción aca).

Desde el primer momento todo bien, hasta que por necesidad, tuve que instalar win server 2012 (lo necesitaba para realizar unas pruebas con NAT64). Se me presentaron muchos problemas a la hora de instalarlo, incluso sobre vmware. En linux nunca se me reinició la máquina, incluso haciendo pruebas con Xen, mientras que en win sí, al primer reinicio (pantallazo azul) el problema era obvio; solo restaba iniciar memtest y listo, memorias malas. NOTA: Para probar memorias con memtest, es recomendable probar un solo módulo a la vez.

Para realizar el proceso de devolución o RMA, ingresé al sitio de soporte y garantía de Corsair aca (), luego me registré en el sitio https://corsair.secure.force.com y seguí las instrucciones para iniciar el proceso.

El proceso fue muy rápido y sencillo, solo aperturas el ticket seleccionando el producto (Memoria RAM), seleccionas el modelo (CMZ8GX3M2A1600C9B en mi caso), número de lote de las memorias, describir el problema presentado (en mi caso ya hay uno predefinido, I have tested the memory with memtest, and it shows errors) y datos como marca y modelo de la Motherboard, modelo de CPU y sistema operativo.

Al día siguiente de haber abierto el ticket, me responden solicitando fotos de las memorias y su caja; donde se pueda observar el lot number; archivo pdf de la factura (en este caso, busque en mi historial de amazon e imprimí en pdf la orden de compra) y por último, una foto del memtest donde se aprecien los errores. Una vez suministrada esta información, en un día me fue aprobado el RMA, me enviaron a mi cuenta de correo un link donde se descarga la etiqueta que contiene el número de RMA, la dirección de envío del producto defectuoso (también aparece la dirección donde enviarán el producto de reemplazo) y las instrucciones de embalaje del producto.

Para el envío de las memorias, fuí a un mail boxes etc y me ofrecieron el envío por Fedex (el envío me costo poco menos de 700Bs). Para realizar el envío, suministré las memorias malas, la factura de la compra y la etiqueta enviada por Corsair (allí estan los datos del departamento de RMA Corsair para el continente Americano, Hayway CA, USA), ellos embalan el producto en una caja estandar (cajas utilizadas por Fedex para realizar envíos internacionales) y se realiza el papeleo para el envío. Es importante que en la caja se pueda observar lo siguiente: RMA # xxxxxx (se puede escribir con marcados); de esta manera una vez llegado el paquete, corsair lo identifica rápidamente.

El envío por Fedex se tardó unos 3 días en llegar, y 24 horas despues de haber llegado, me enviaron unas memorias nuevas desde Taiwan. En el caso de Corsair, los productos de reemplazo, los envían por UPS y Fedex, dependiendo del tamaño.

En total, el proceso duró 19 días, desde que abrí el ticket para iniciar el proceso de devolución hasta que me llegaron las memorias nuevas.

Hasta la proxima !

Jueves 25 de septiembre de 2014

Donde encontrar increibles Fotos Gratuitas

Uno de los retos mas grandes cuando nos toca realizar un website o una publicidad en general es encontrar fotografías geniales a un buen costo (o gratis dependiendo del cliente), y no es que sea malo pagar por fotografías, pero a veces el cliente es pequeño y pues el presupuesto no alcanza. En la red hay miles de servicios que proveen fotografías de alta calidad por un costo de suscripción mensual, por paquete o por fotografía, pero hay un mundo de sitios que ofrecen fotografías de forma gratuita bajo una licencia amigable para esas necesidades que tanto tenemos como diseñadores. Veamos algunos de mis favoritos:

dttsf

Death to Stock Photo es un servicio al cual te suscribes dejando tu email en su website, y mensualmente envía sets de 10 fotografías ambientadas usualmente en el tema del mes, con una calidad increíble y una variedad super útil. Cada vez que recibes un correo de ellos te emocionas solo al ver el titulo porque sabes que una explosión de creatividad ha llegado a tu correo.

pixabay

Pixabay es un excelente sitio donde el orden de sus etiquetas y categorías son la clave para encontrar lo que quieras, cuando quieras. No requiere registrarse y su interfaz es muy parecida a la de 500px, por lo que encontrar y descargar contenido es pan comido.

nos

New Old Stock es una colección de fotografías públicas antiguas que están libres de todo tipo de restricción de derechos de autor. Es muy a lo tumblr y es algo difícil ubicar fotos por categorías o etiquetas, sin embargo, la cantidad de fotografías referenciales a artículos y momentos históricos que tiene es simplemente hermosa.

littlevisuals

Little Visuals sigue el estilo de Death to StockPhoto pero cada 7 días. Tiene fotos hermosas bajo dominio público pero lo bueno es que en su web, tienen a disposición todo el histórico de packs, por lo que si te perdiste uno o apenas te estás uniendo, puedes revisar los packs anteriores y bajar lo que necesites.

picjumbo

PicJumbo es un sitio que disfruta de una variedad abismal de contenido, además de tener un excelente plugin para tu browser que te avisa cuando hay contenido nuevo. Se agregan fotos nuevas diariamente, así que nunca te quedarás sin contenido fresco para tus necesidades.

Y recuerda que las votaciones para Mejor Blog de SoftwareLibre aún están abiertas, vota si aún no lo has hecho!!!

flattr this!

Announcing European Hosting for OpenShift Online

Open Shift

Desarrolladores OpenShift online de todo el mundo han creado más de 2 millones de solicitudes. Hoy, estamos dando otro paso para apoyar a nuestra base de clientes global en crecimiento mediante la adición de una nueva opción de alojamiento en Irlanda.

Ahora se puede ejecutar sus aplicaciones en engranajes de producción con la misma funcionalidad de nuestras localidades en Estados Unidos o lugares de alojamiento europeas

Caracteristicas

  • Baja latencia para aplicaciones de producción
  • Engranajes de producción, mercado, y Más
  • Actualización de Herramientas de Cliente (RHC)

Alguna sugerencia?

Pues, accedan a https://openshift.uservoice.com/forums/258655-ideas donde pueden dejar o proponer ideas para hacer que experiencia de usuario en OpenShift sea mejor.

Miércoles 24 de septiembre de 2014

Como hacer videos para Instagram usando Kdenlive + Instashot

Te has preguntado como hago mis videos de Instagram? Trabajar con Kdenlive es muy fácil y una de las cosas que mas me gusta es que puedes arrastrar cualquier video, imagen o audio y automáticamente se cargará en la aplicación. Hacer un video en Kdenlive es como armar un rompecabezas, solo debes arrastrar las piezas que ya cargaste y ordenarlas. Puedes separar las pistas, cortarlas, agregarles efectos y mucho más. Poco a poco iré explicando como trabajar mas detalladamente con Kdenlive, pero primero, quiero que vean la potencialidad de esta aplicación y se enamoren de ella como yo lo he hecho.

Una vez exportado nuestro video mp4 lo copiaremos a nuestro teléfono, abriremos instashot y selecionaremos video. Navegaremos hasta encontrar nuestro video y lo cargaremos a la aplicación. En este punto verás una serie de opciones en la parte inferior, seleccionaremos Fit de ajustar, y si queremos que el video sea cuadrado como instagram, seleccionaremos Full. Puedes probar las otras opciones si te da curiosidad. Cuando estés feliz con el encuadre, pulsa el visto bueno a la derecha y en la parte superior encontrarás el enlace directo para cargarlo a instagram. Tarda un poco ya que le baja la calidad, al menos ese fue mi caso y eso te dará la opción de publicar de una vez.

Y así es como realizo los videos que me gusta compartir con ustedes en instagram y que ultimamente “creo” que los han hecho reir un monton. Recuerden que sus dudas se convierten en podcast, así que no sean timidos y dejen un comentario… ahh…. y si les gusta mi contenido, no olviden ir a portal programas y votar por tatica.org como mejor Blog de SoftwareLibre, su voto significa mucho para mi!

flattr this!

Martes 23 de septiembre de 2014

Valencia Software Libre: Xanadu GNU / Linux - Distro Venezolana. version 0.6.0

Domingo 21 de septiembre de 2014

Xanadu GNU / Linux

Alt Text

Es un derivado de Debian que utiliza SID como base y LXDE como entorno de escritorio, pensada para ser ligera y a la vez útil, contiene herramientas para rescate de sistemas, análisis forense y navegación anónima, además de todo lo necesario para su uso en el escritorio.

El grupo de desarrollo de Xanadu GNU/Linux se complace en anunciar la versión 0.6.0 de nuestra distribución. Esta versión viene llena de muchos cambios importantes, entre los que podemos mencionar:

  • Se sustituye el kernel original por el kernel liquorix.
  • Se sustituye BASH por FISH como shell por defecto.
  • Se agrega soporte para XFS y BTRFS además de EXT4 en el instalador.
  • Si se instala usando XFS se agregan parámetros dedicados al sysctl.conf.
  • Se incorpora apparmor.
  • El script “entorno” ahora nos da mas información.
  • Los valores “shmmax” y “shmall” se calculan durante el arranque.
  • Se agrega “tcp_mtu_probing” al sysctl.conf.
  • Se activa el soporte para IPv6.
  • La opción “activar seguridad” fue movida desde el script adicionales al script post-instalador y se crea la opción “desactivar seguridad”.
  • Se agrega la opción para instalar hplip-gui desde el post-instalador.
  • Se agrega la opción para desactivar compton en adicionales.
  • Se agrega el paquete florence (teclado en pantalla)
  • Se agregan los siguientes paquetes: joystick, x11-touchscreen-calibrator, xinput-calibrator, xserver-xorg-input-elographics, xserver-xorg-input-multitouch.
  • Se eliminan los paquetes plymouth, usbview y lxlauncher.
  • Se desactiva la búsqueda automática de la partición de persistencia para acelerar el arranque.

En el caso de la imagen ISO llamada minimal se elimina debido a su poca popularidad y para simplificar el proceso de creación de las ISO, en su lugar se utilizara el script “modo-server” que se encarga de realizar limpieza sobre un xanadu ya instalado dejando solo los componentes incluidos originalmente en la imagen minimal.

También se cambiara la frecuencia de publicación de nuevas versiones de la distribución que a partir de ahora se harán trimestralmente, estando programada la publicación de la próxima versión para principios del mes de diciembre, como siempre en la sección de descarga se encuentran los nuevos enlaces:

https://xanadulinux.wordpress.com/descarga/

NOTA: Hay un error SIGSEGV en brasero en la imagen i386 que impide su ejecución, este error ya fue reportado a sus desarrolladores y esta a la espera de una solución. Después de instalar Xanadu i386 solo deberá realizar una actualización para corregir el problema.

Miércoles 17 de septiembre de 2014

Usando SSH para actualizar WordPress

En estos días me ha tocado atender un nuevo cliente, la gente de 4lochas.com, un portal de música y variedades que tiene rato hosteado con nosotros, pero que cambió recientemente de administración. Luego de una buena cantidad de setbacks (menores y mayores), pusimos a andar el sitio. Y, si bien es cierto que hay un par de caídas de vez en cuando, el sitio está operativo la mayor parte del tiempo. Esas cosas se van a ir corrigiendo a medida que se van afinando los detalles.

Entre las cosas que me solicitaba, estaban las de actualizar plugins y temas y esas cosas. Obviamente, lo primero que se hace con un cliente nuevo es darle sus credenciales de usuario. Pero, en el caso de mis servidores, hay una configuración estándar de ssh, en la que PasswordAuthentication está desactivado, y sólo puedes loguearte si tu llave pública está añadida en el authorized_keys correspondiente. Por lo que el cliente debe generar llaves ssh para poder añadirlas a su archivos de llaves autorizadas. Desafortunadamente, putty no es particularmente sencillo en su uso de llaves. Al menos, no para mí que sólo lo he usado un par de ocasiones, y nunca desde mis equipos.

En fin, revisando por el internés alguna forma de automatizar el proceso de autenticación vía llaves ssh en wordpress, conseguí este artículo en el que explican paso a paso lo que debe hacerse. La cosa es que está hecho para distribuciones basadas en RedHat.

No voy a ahondar mucho en cómo se instala ssh, cómo creas llaves públicas, cómo accedes a ellas y cómo las llevas al servidor. De esos hay muchísimos artículos por toda la internet que está a un googleo de distancia. Lo que sí voy a decirles es qué necesitan desde ese punto en adelante para tener el wordpress andando en [una distro basada en] debian.

Lo primero, instalar libssh2-php

apt-get install libssh2-php

Luego, añadir esto en su wp-config.php. Les sugiero que las añadan luego de los salt strings.


define('FTP_PUBKEY','/home/tu_usuario/.ssh/id_rsa.pub');
define('FTP_PRIKEY','/home/tu_usuario/.ssh/id_rsa');
define('FTP_USER','tu_usuario');
define('FTP_PASS','hackme');
define('FTP_HOST','127.0.0.1:22');

Donde:
FTP_PUBKEY: Es la llave pública. Usualmente se aloja en ~/.ssh
FTP_PRIVKEY: Es la llave privada. Usualmente se aloja en ~/.ssh
FTP_USER: Obviamente, tu usuario
FTP_PASS: El password.
FTP_HOST: En este caso, 127.0.0.1, porque se supone que estás descargando local en tu servidor. Puedes usar un TLD o incluso un subdominio.

Ya con eso no deberías requerir configurar nada más para actualizar o instalar cualquier cosa en WordPress. De hecho, lo probé actualizando a WP4, añadiendo un nuevo tema e instalando plugins y actualizaciones requeridas sin ningún inconveniente.

Viernes 12 de septiembre de 2014

Héctor Colina

Optimizando recursos en tu computador

En aras de optimizar el uso de un minicomputador que estoy utilizando, he venido realizando una serie de instalaciones controladas obviando muchos de  los paquetes predefinidos que ofrece el instalador de Debian, en este caso.

Al momento de la instalación de Debian, utilicé la versión testing:

hector@helga:/tmp$ cat /etc/debian_version 
jessie/sid
hector@helga:/tmp$

Y como manejador de ventanas e17 junto con lightdm como gestor de inicio de sesión gráfica.

Esta combinación me ha permitido ahorrar recursos en el equipo VIT M1100, computador de procesador  Intel Atom CPU N270 a 1.60GHz con 2 Gb de RAM; por ejemplo, no es infrecuente que en ese equipo tenga funcionando, como ahora, LibreOffice, un navegador web con 10 ventanas abiertas, una consola (utilizo lxterminal) con 3 pestañas abiertas y el rendimiento del mismo sea bastante aceptable

 hector@helga:/tmp$ free
 total used free shared buffers cached
Mem: 2062084 1331972 730112 112288 48432 671848
-/+ buffers/cache: 611692 1450392
Swap: 3906556 0 3906556
hector@helga:/tmp$

Sin embargo, una de las cosas que extrañé fue una herramienta que me permitiese utilizar la webcam, para ello, utilicé la herramienta fswebcam, disponible en los repositorios de Debian y que se utiliza de la siguiente forma:

hector@helga:/tmp$ fswebcam -r 1024x768 --jpeg 200 -D 1 captura.jpg

Donde:

r es la resolución

–jpeg es la resolución de salida del formato a utilizar

-D es el retardo que se utilizará para que luego de activada la cámara se tome la fotografía, en algunos casos, este valor debe ser mayor para permitir que el sensor de la cámara calibre la luz exterior

Acá un ejemplo de la captura realizada.
captura

Espero les sea útil esta entrada.

Viernes 29 de agosto de 2014

Oliver Rivas

Oliver Rivas
orvtech.com

Eliminando todos los mensajes directos de Twitter con Python

Sigo en mi travesía por aprender Python y que mejor forma que solucionar problemas en funciona a la privacidad.

Varias personas me comentaron lo tedioso que es eliminar mensajes privados en Twitter así que decidi hacer una herramienta que me permita automatizar todo esto.

Lo primero es crear una app en twitter visitando apps.twitter.com y otorgarle permisos de lectura, escritura y DMs. Allí mismo pueden generar el consumer_key, consumer_secret, access_token_key y el access_token_secret.

El script no es nada complejo y de hecho hay oportunidades para mejorarlo, aqui se los dejo:

# https://github.com/orvtech/Python-tools-for-twitter
import json
import requests
from requests_oauthlib import OAuth1


consumer_key='<YOUR CONSUMER KEY HERE>'
consumer_secret='<YOUR CONSUMER SECRET HERE>'
access_token_key='<YOUR ACCESS TOKEN HERE>'
access_token_secret='<YOUR ACCESS TOKEN SECRET HERE>'


def get_messages_ids():
  api_url='https://api.twitter.com/1.1/direct_messages.json'
  payload = {'count':'200', 'cursor':'-1', 'skip_status':'1'}
  auth = OAuth1(consumer_key, consumer_secret, access_token_key, access_token_secret)
  r = requests.get(api_url, stream=False, auth=auth, params=payload)
  if r.headers['x-rate-limit-remaining'] and r.headers['x-rate-limit-remaining'] == "0":
    print("We reached rate limit for ", api_url)
    print("Try again at", r.headers["x-rate-limit-reset"])
    quit()
  DMs = json.loads(r.content)
  message_ids=[]
  for x in range(len(DMs)):
    current_ids=DMs[x]['id']
    message_ids.append(current_ids)
  api_url='https://api.twitter.com/1.1/direct_messages/sent.json'
  payload = {'count':'200'}
  r = requests.get(api_url, stream=False, auth=auth, params=payload)
  if r.headers['x-rate-limit-remaining'] and r.headers['x-rate-limit-remaining'] == "0":
    print("We reached rate limit for ", api_url)
    print("Try again at", r.headers["x-rate-limit-reset"])
    quit()
  DMs = json.loads(r.content)
  for x in range(len(DMs)):
    current_ids=DMs[x]['id']
    message_ids.append(current_ids)
  return message_ids


def nuke_messages(DMs):
  for x in DMs:
    api_url='https://api.twitter.com/1.1/direct_messages/destroy.json'
    payload = {'id':x}
    auth = OAuth1(consumer_key, consumer_secret, access_token_key, access_token_secret)
    r = requests.post(api_url, stream=False, auth=auth, params=payload)


while True:
  DMs = get_messages_ids()
  if DMs and len(DMs) > 0:
    print('Deleting:', DMs)
    nuke_messages(DMs)
  else:
    print('There appears that there are no more DMs', DMs)
    break

Usa solo 2 funciones, una en la que invoca primero los primeros 200 mensajes recibidos y luego los primeros 200 mensajes enviados. Tras evaluar si en realidad existen mensajes, se le pasan los IDs de los mensajes a eliminar a la segunda función y se repite este proceso hasta que no existan mas IDs a eliminar.

Tanto las llamadas de al API para saber los IDs de los mensajes enviados como las de los mensajes enviados tiene un limite así que implemente mecanismos para monitorear si se llego al limite leyendo las cabeceras de las peticiones HTTP.

Por lo pronto pueden hacer un fork de este repositorio de github En un futuro me gustaría convertirlo en una aplicación web usando flask o algo por ese estilo.


Miércoles 27 de agosto de 2014

Milton Mazzarri

Milton Mazzarri
milmazz

How to document your Javascript code

Someone that knows something about Java probably knows about JavaDoc. If you know something about Python you probably document your code following the rules defined for Sphinx (Sphinx uses reStructuredText as its markup language). Or in C, you follow the rules defined for Doxygen (Doxygen also supports other programming languages such as Objective-C, Java, C#, PHP, etc.). But, what happens when we are coding in JavaScript? How can we document our source code?

As a developer that interacts with other members of a team, the need to document all your intentions must become a habit. If you follow some basic rules and stick to them you can gain benefits like the automatic generation of documentation in formats like HTML, PDF, and so on.

I must confess that I’m relatively new to JavaScript, but one of the first things that I implement is the source code documentation. I’ve been using JSDoc for documenting all my JavaScript code, it’s easy, and you only need to follow a short set of rules.

/**
 * @file Working with Tags
 * @author Milton Mazzarri <me@milmazz.uno>
 * @version 0.1
 */

var Tag = $(function(){
  /**
   * The Tag definition.
   *
   * @param {String} id - The ID of the Tag.
   * @param {String} description - Concise description of the tag.
   * @param {Number} min - Minimum value accepted for trends.
   * @param {Number} max - Maximum value accepted for trends.
   * @param {Object} plc - The ID of the {@link PLC} object where this tag belongs.
   */
  var Tag = function(id, description, min, max, plc) {
    id = id;
    description = description;
    trend_min = min;
    trend_max = max;
    plc = plc;
  };

  return {
    /**
     * Get the current value of the tag.
     *
     * @see [Example]{@link http://example.com}
     * @returns {Number} The current value of the tag.
     */
    getValue: function() {
      return Math.random;
    }
  };
 }());

In the previous example, I have documented the index of the file, showing the author and version, you can also include other things such as a copyright and license note. I have also documented the class definition including parameters and methods specifying the name, and type with a concise description.

After you process your source code with JSDoc the result looks like the following:

usejsdoc

In the previous image you see the documentation in HTML format, also you see a table that displays the parameters with appropriate links to your source code, and finally, JSDoc implements a very nice style to your document.

If you need further details I recommend you check out the JSDoc documentation.

How to document your Javascript code was originally published by Milton Mazzarri at milmazz on August 27, 2014.

Cómo extender un volumen en LVM

A veces es necesario extender un volumen lógico, expandiendo el volumen físico donde está alojado. Si este es el caso, puedes seguir este ejemplo que extiende un volumen de 450 GB a 500 GB: Primero consultamos a geometry del disco

:~# fdisk -l /dev/sdb
Disk /dev/sdb: 483.2 GB, 483183820800 bytes
 255 heads, 63 sectors/track, 58743 cylinders, total 943718400 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk identifier: 0x0001178e

Luego de expandir el volumen, se fuerza a que se rescanee el volumen

:~# echo 1 > /sys/block/sdb/device/rescan

Consultamos nuevamente la geometría del disco

:~# fdisk -l /dev/sdb
Disk /dev/sdb: 536.9 GB, 536870912000 bytes
 255 heads, 63 sectors/track, 65270 cylinders, total 1048576000 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk identifier: 0x0001178e

Como puede verse el tamaño del disco aumentó pero solo lo sabe del sistema operativo, ya que a nivel de LVM sigue teniendo la misma información porque no se ha expandido el volumen físico:

:~# pvs
 PV VG Fmt Attr PSize PFree
 /dev/sda5 debian lvm2 a-- 3.76g 0
 /dev/sda6 debian lvm2 a-- 13.00g 0
 /dev/sdb svn_vg lvm2 a-- 450.00g 0

Si expandimos el volumen físico con la siguente orden:

# pvresize /dev/sdb
 Physical volume "/dev/sdb" changed
 1 physical volume(s) resized / 0 physical volume(s) not resized

Y ahora consultamos los el espacio de los volúmenes físicos veremos el espacio agregado:

:~# pvs
 PV VG Fmt Attr PSize PFree
 /dev/sda5 debian lvm2 a-- 3.76g 0
 /dev/sda6 debian lvm2 a-- 13.00g 0
 /dev/sdb svn_vg lvm2 a-- 500.00g 50.00g

Ahora se debe expandir el volumen lógico y la dimensión de sistema de archivos en caliente. Ambas cosas se pueden hacer con una sola orden:

:~# lvresize -r -L +50G /dev/mapper/svn_vg-svn
 Extending logical volume svn to 500.00 GiB
 Logical volume svn successfully resized
 resize2fs 1.42.5 (29-Jul-2012)
 Filesystem at /dev/mapper/svn_vg-svn is mounted on /var/data/svn; on-line resizing required
 old_desc_blocks = 29, new_desc_blocks = 32
 Performing an on-line resize of /dev/mapper/svn_vg-svn to 131070976 (4k) blocks.
 The filesystem on /dev/mapper/svn_vg-svn is now 131070976 blocks long.

Finalmente si consultamos el espacio disponible tendremos los 50 GB adicionales en el sistema de archivos:

:~# df -h
 Filesystem Size Used Avail Use% Mounted on
 rootfs 993M 287M 655M 31% /
 udev 10M 0 10M 0% /dev
 tmpfs 397M 228K 397M 1% /run
 /dev/mapper/debian-root 993M 287M 655M 31% /
 tmpfs 5.0M 0 5.0M 0% /run/lock
 tmpfs 794M 0 794M 0% /run/shm
 /dev/sda1 228M 34M 183M 16% /boot
 /dev/mapper/debian-home 2.0G 39M 1.9G 3% /home
 /dev/mapper/debian-tmp 3.9G 7.1M 3.7G 1% /tmp
 /dev/mapper/debian-usr 2.0G 869M 1.1G 46% /usr
 /dev/mapper/debian-var 6.7G 2.1G 4.3G 33% /var
 /dev/mapper/svn_vg-svn 493G 432G 62G 88% /var/data/svn

Jueves 21 de agosto de 2014

Adios Linux

Está Escrito:
Pero el hombre natural no percibe las cosas que son del Espíritu de Dios, porque para él son locura, y no las puede entender, porque se han de discernir espiritualmente. (1 Corintios 2:14)

OJO esto es lo que Piensan Los que no Conocen Linux,

Deja tu Comentario..

 Adios Linux

Hace unas semanas alguien me dijo "Mira, un tablet con arranque dual Linux/Android" y como entonces pensé, a estas alturas... ¿A quien le importa Linux?

Esta claro que la oportunidad que tuvo Linux en los sistemas de escritorio con los netbooks ha sido la única que ha tenido de inundar el mercado de escritorio, ocasión que fue desaprovechada  y no volverá a suceder. Ahora a nadie le importa Linux ni sus escritorios fuera del ámbito estrictamente profesional. Y mientras vive su época dorada en Android, a nivel de escritorio esta acabado. Si linux no fue capaz de quitarle un misero 2% de cuota a Windows cuando la gente usaba Windows 98, XP y Vista, menos lo sera ahora que todo usuario poco avanzado esta migrando a iPads o tablets android y el usuario avanzado esta con Windows 7.

Como he dicho, Linux con los netbooks tuvo la mejor oportunidad posible para copar un mercado. Equipos pequeños, baratos, sin potencia donde windows 7 iba muy mal, no estaba adaptado y tenían un uso tan limitado a la navegación web que Linux podía hacer todo sin problema alguno, o eso decían. Pero no consiguió nada, la lentitud y conservadurismo con la que se desarrollan los sistemas de escritorio de Linux lo volvieron a dejar fuera del mercado. Yo mismo mostré en un articulo de 2010 como con un poco de ingenio y un solo programa se podía dejar el escritorio GNOME en una autentica maravilla adaptada a netbooks con esfuerzo prácticamente nulo ¿Y que hacían las grandes distribuciones y escritorios? La mayoría obvio el mercado de los netbooks y no le presto la suficiente atención. Otras como canonical se adentraron en un desarrollo faraonico de un nuevo sistema de escritorio que se ha ganado muchísimas criticas, empezando porque salio a la luz en pañales.

Las señales del final
Un ejemplo de esta decrepitud es la comunidad Linux que visitaba regularmente desde 2008. Casi todos los usuarios que no eran unos fanaticos lo habían abandonado para irse a Windows o Mac. La comunidad se ha convertido básicamente en un SAT donde diariamente se arreglan problemas de un SO, con cientos de citas de la terminal, que casi nunca encontraban solución.

Desde que abandone Linux, hace un año y pico, no he visto motivo alguno para volver, he ganado una despreocupación por el ordenador absoluta, que no tenía con Linux. Pues para usarlo uno tiene que estar eternamente luchando contra los elementos. Hace no mucho tuve una charla con un IT que derivo a la situación de linux en su casa.

 "Mira, en la oficina tengo algún servidor Linux y es un todoterreno, lleva en pie desde hace dos años sin ningún problema. Pero en casa algo tan sencillo como ver un video flash a pantalla completa es imposible, cuelgues, cuelgues y más cuelgues, y basicamente es para lo único que uso windows en casa. He probado ya tropecientas distros, versiones,... y siempre con problemas. Al final me he comprado una licencia de Windows 8."

Creo que aqui esta una de las claves del fracaso de Linux en el escritorio. Que ya he comentado tantas veces.

¿Alguien tiene la culpa?
¿En algún momento piensa alguien en hacer algo de autocritica? ¿O van a seguir echando balones fuera como llevan haciendo una década? Hace no mucho Miguel de Icaza escribió un articulo en el que daba por muerto a Linux en los sistemas de escritorio y exponía lo que el veía como los problemas que llevaron a Linux a tal fracaso ¿Cual fue la respuesta de la gente? ¿Aceptarlo? ¿Intentar buscar otra explicación a este fracaso? Porque el fracaso es innegable salvo para cuatro gatos a los que es mejor directamente ignorar. No recuerdo una corriente de opinión que desmontara sus argumentos, obviando a Torvalds que va por libre. La mayoría de comentarios que escuche en su día son dignos de patio de colegio, atacando a Icaza por tener un Mac, por desarrollar Mono, por su papel en Novell y Microsoft,... Todos esos pecados que en la comunidad linux uno no puede permitirse, como tener opinión propia. Vamos, que mientras alguien hacia por fin una autocritica sacando los trapos sucios, incluso los suyos, el resto se dedicaron a demostrar la mentalidad de crió que ha rodeado siempre a Linux y que han sido en parte su tumba porque no permitían un debate serio y adulto.

Adios
Como usuario de escritorio este articulo es mi despedida completa de Linux y de su comunidad. Mientras que hace un tiempo abandone el sistema operativo mientras seguía un poco al tanto de las novedades, esta vez ya es despedida completa del sistema. Si vuelvo sera en una estación de trabajo, un servidor, un movil android,... o quien sabe, quizás una futura consola de Valve.

Y si, podéis cabrearos, podéis hacer lo de siempre que es llamarme de todo (especialmente los insultos latinos que solo hacen partirme el culo de la risa), podéis negar todo, podéis mentir sobre mi, podéis sacar de contexto lo que he dicho, podéis hablar del Top500 y de Android, podéis decir que me equivoco y que todo es falso, decir que odio el software libre aunque lo use todos los días,... Podéis hacer mil cosas,... Lo que no podéis hacer es tener un 2% de cuota de mercado.


Lo siento, linux, YOU LOSE!

Domingo 03 de agosto de 2014

David Moreno

David Moreno
dm's blog

New hosting for Planeta Linux

Just a very quick shout out.

A few weeks/months ago, Planeta Linux lost its hosting. As I'm less and less involved on third party projects, it was a bit hard for me to just put it somewhere else. Víctor, however, approached me and offered to pay for it. A few days later, we hosted Planeta Linux on one of his hosting instances. A big round of applause goes to him! He is the one making that community possible.

Over and out.

Domingo 27 de julio de 2014

Tarea de Django-Celery desde un URL.

En el artículo anterior (Restful API con Django-tastypie y Django-Celery ) se mostró como pasarle datos a django desde su interprete de comandos, en este arículo se explicará como pasarlo desde el navegador o un script en python que lo haga por nosotros.

Recapitulando la parte del código que captura el url se maneja en el archivo urls.py que tiene lo siguiente:
url(r'^enviar/', celery_views.task_view(tasks.RecNums)),

Al abrir el url http://127.0.0.1:8080/ se tiene la siguiente imagen de una captura de pantalla:



Como django está en modo debug nos muestra esa página, la cual dice los urls tienen que manejar el orden que se muestra (admin,api, enviar y los otros dos con identificación de procesos).

Django devuelve mensaje 404, como se muestra a continuación:


En el artículo anterior se uso el interprete de comandos de Django con el siguiente código:
>>>import json
>>>from pasarela.apps.sms.tasks import RecNums
>>>datos = '{"numeros": ["34225673531", "34265673531", "34365673531", "34245673531", "34345673531"], "mensaje": "xyzw", "cantnumeros": 5,"evento":6}'
>>>resultado = RecNums.delay(datos)
>>>resultado.get()
'Se enviaron: 5'

Como se ve, datos es un string que contiene entre llaves un conjunto de datos, lo que está entre las comillas es un diccionario de python, por esa razón cuando la función RecNums recibe datos convierte el string que en sí es un json, el cual pasa de ser un tipo str a un tipo dict:
>>>type(datos)
str
>>>diccionario = json.loads(datos)
>>>type(diccionario)
dict

Ahora bien, se tiene que el url a usar debería ser algo como:
http://127.0.0.1/enviar/?datos=
Donde lo que va luego del igual debería ser el jason que se está pasando a la función ( '{"numeros": ["34225673531", "34265673531", "34365673531", "34245673531", "34345673531"], "mensaje": "xyzw", "cantnumeros": 5,"evento":6}' ). Este es el json, el problema que se tiene es que el url no está bien construído, para ello se mostrará en un script python como se abre el url pasandole el json (se muestra en la siguiente figura):


A continuación se muestra el log de celery donde se ve que procesa las tareas del envío de cada mensaje a su número celular respectivo:

Y para terminar se muestra el log de Django al recibir el URL que se paso en el script donde devuelve el código 200:

Así que para poder pasar por medio de un url sus parámetros se tiene que realizar una conversión a formato url de los datos que se tienen en el json.

Puntero del mouse no visible en gnome

Download PDF

Si por alguna razón utilizando alguno de los componentes de gnome (como gnome-settings-daemon en mi caso porque gnome-terminal todavía me gusta) el puntero del mouse no es visible pero aún funcional, entonces lo más probable es que tengas que ejecutar:

dconf write /org/gnome/settings-daemon/plugins/cursor/active false

Este problema se da puesto que Gnome esconde el puntero cuando se detecta algún dispositivo touch¹ (vaya estupidez cuando lo touch no es la pantalla, pero el trackpad). Así pues, es necesario hacer entender al !@#$%&*@# Gnome que no se trata de una !@#$%^ pantalla touch pero de un !@##$%%^ multi-touch trackpad.

1. https://bugs.archlinux.org/task/34901

Lunes 21 de julio de 2014

Convertir archivo de audio WMA a formato MP3

Vamos a convertir archivos VMA a MP3, de una manera bastante simple y directa. Los pasos descritos acá son de utilidad para esas ocasiones donde te bajas un audio WMA pero tu reproductor, celular, etc no lee ese formato, así que lo único que quieres es transformarlo a MP3 para que pueda reconocerlo. El procedimiento […]

De .NEF a .JPG en Linux sin perder calidad

El día de ayer mi amiga Gabriela me comentó que estaba tratando de transformar archivos .NEF (formato electrónico de archivos RAW de Nikon) a .JPG y que estaba perdiendo calidad en la imagen final, y que además tenía un lote de unas 2000 fotografías que deseaba procesarlas a JPG sin pasar por un proceso manual (ella usa Darktable ó UFRaw para ello). Durante un rato estuve jugando con las herramientas de imagemagick y notaba la alta perdida de calidad, por ejemplo:

Imagen Original .NEF

 

Imagen JPG procesada con Darktable/UFRaw

 

Para ello escribí un pequeño y sucio script en bash que:

  • Convierte los archivos .NEF a .PNG y luego con imagemagick transforma el PNG a JPG (método sucio que funciona usando netpbm, dcraw y imagemagick).
  • Procesa un lote de .NEF que estén ubicados en el directorio donde se corra el script.
#/bin/bash
# Instrucciones:
# 
# 1. Para que este script funcione, necesita tener instalado: netpbm, dcraw, imagemagick
#
# sudo aptitude install netpbm dcraw imagemagick
#
# 2. Setear permisos de ejecucion al script
# chmod +x nef_a_jpg.sh 
#
# Enjoy :D
#
# Por: Juan Angulo Moreno <apostols@gmail.com> 2014-07-20
 
echo "Preparando el ambiente..."
 
total_archivos=`ls *.NEF| wc -l` 
echo "Iniciando conversion... Total de archivos a convertir: $total_archivos"
 
# Que comience la fiesta
for ARCHIVOS in *.NEF ; 
do 
	nombre_base=`basename "$ARCHIVOS" .NEF`;
	echo "Conviertiendo $nombre_base.NEF a JPG...";
	dcraw -c -w $ARCHIVOS | pnmtopng > $nombre_base.png;
	convert $nombre_base.png $nombre_base.jpg
	echo "Listo."
done

Sábado 19 de julio de 2014

Restful API con Django-tastypie y Django-Celery

Continuando con los artículos sobre django, en este caso se usará django-celery para envío de mensajes a un servidor kannel (servidor sms) y django-tastypie para mostrar el resultado por medio de API rest full con json.
En los dos artículos anteriores Manejo de colas de RabbitMQ en django con django-celery y Restfult API con django tastypie se tiene la base de este artículo. Este artículo se basa en el ejemplo de la mensajería sms del artículo de Restfult API con django tastypie (todo el proceso de creación del proyecto y de la aplicación sms fue explicada en ese artículo).

La idea ahora es poder mostrar los sms listados por evento, no es necesario estar creando una tabla que herede de las otras dos, esto será posible gracias a tastypie en una consulta del json.

Se usará como base de datos sqlite3. A continuación se muestra el archivo settings.py:
#Archivo settings.py:
#Configuración de la base de datos sqlite3
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'sms.db',                      # Or path to database file if using sqlite3.
        'USER': '',                      # Not used with sqlite3.
        'PASSWORD': '',                  # Not used with sqlite3.
        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
    }
}





#Zona horaria y localización


TIME_ZONE = 'America/Caracas'




LANGUAGE_CODE = 'es-ve'


#Aplicaciones instaladas (djcelery,pasarela.apps.sms,tastypie y south)
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # Uncomment the next line to enable the admin:
    'django.contrib.admin',
    'djcelery',
    'pasarela.apps.sms',
    'tastypie',
    'south',
    # Uncomment the next line to enable admin documentation:
    # 'django.contrib.admindocs',
)


#Conexión al servidor kannel 
direccion = "127.0.0.1"
portsms = "13013"
portadmin  = "13000"
usuario = "kannel"
clave = "kannel"
----------------------

El archivo pasarela/apps/sms/models.py:
#Archivo pasarela/apps/sms/models.py
from django.db import models

#Se crea la tabla Evento que contiene los campos evento (número del evento), el estatus del mismo (si se #termino el evento o no y si no termino fue por falla o no.
class Evento(models.Model):
    evento = models.IntegerField(primary_key=True)
    estatus = models.BooleanField(default=False)

    def unicode(self):
       evento = "Evento: %s, Estatus: %s , Falla: %s" %(self.evento,self.estatus,self.falla)
       return evento

#Se crea la tabla HistoricoSMS donde se tiene un campo
#foreignkey de la tablla evento, el mensaje, el número de celular, el estatus si se envío o no o si fallo.
class HistoricoSMS(models.Model):
    evento = models.ForeignKey(Evento)
    mensaje = models.CharField(max_length=150)
    numcel = models.CharField(max_length=11)
    estatus = models.BooleanField(default=False)

    def unicode(self):
        mensaje = "%s, %s, %s, %s, %s"  %(self.evento.evento,self.numcel,self.estatus, self.mensaje,self.falla)
        return mensaje
--------------------


Archivo pasarela/apps/sms/admin.py:
#Archivo pasarela/apps/sms/admin.py
#En este archivo se define que las tablas Evento e HistoricoSMS se puedan visualizar desde la #administración de django.
from django.contrib  import admin
from pasarela.apps.sms.models import HistoricoSMS,Evento


admin.site.register(HistoricoSMS)
admin.site.register(Evento)


Archivo pasarela/apps/sms/api.py (archivo para crear el api restful de django-tastypie), en este caso tiene varias modificaciones con respecto al artículo anterior sobre tastypie, ahora se agrega la variable filtering(más información sobre filtering en el siguiente enlace) que es un diccionario en cada recurso:

#Se importa de tastypie.resources ModelResource, ALL y ALL_WITH_RELATIONS
from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
#Se importa del modelo HistoricoSMS y Evento
from .models import HistoricoSMS,Evento
#Se importa fields de tastypie
from tastypie import fields


class EventoResource(ModelResource):
    class Meta:
        queryset =Evento.objects.all()
        resource_name = 'evento'
#Se muestra todos los eventos
        filtering = {
            'evento': ALL,
        }


class SMSResource(ModelResource):
    evento = fields.ForeignKey(EventoResource, 'evento')
    class Meta:
        queryset = HistoricoSMS.objects.all()
        resource_name = 'sms'
#De evento se muestra todo con relación a el. de estatus se muestra exactamente lo que se necesita,
#acá también se puede usar para las consultas: ['exact', 'range', 'gt', 'gte', 'lt', 'lte'].
        filtering = {
            'evento': ALL_WITH_RELATIONS,
            'estatus':['exact'],
        }
------------------------


El archivo que permite manejar las tareas de celery pasarela/apps/sms/tasks.py :
#Archivo pasarela/apps/sms/tasks.py
from celery import Celery
app = Celery('tasks', broker='amqp://',backend='amqp')
from urllib2 import urlopen
from urllib import urlencode
import urllib2
import json
from time import sleep
from django.conf import settings
from pasarela.apps.sms.models import HistoricoSMS,Evento



#Conexión al servidor kannel (está configuración se puede pasar al archivo settings.py y usarla desde allí
direccion = settings.direccion
portsms = settings.portsms
portadmin  = settings.portadmin
usuario = settings.usuario
clave = settings.clave

#Se define una tarea para celery por medio del decorador @task, se recibe un json para luego sea
# procesado.
@app.task
def RecNums(datos):
    #Se toma el json y se convierte en un diccionario
    diccionario = json.loads(datos)
    #Se instancia la clave Evento(tabla Evento).
    evento = Evento()
    #Se asigna cada variable del diccionario para trabajarlos directamente
    for clave in diccionario.keys():
        if clave == 'mensaje':
            mensaje = diccionario[clave]
        elif clave == 'numeros':
            numeros = diccionario[clave]
        elif clave == 'cantnumeros':
            cantnum = int(diccionario[clave])
        elif clave == 'evento':
            eventoid = int(diccionario[clave])
    #Se crea una lista para agregar todos los números de celular a dicha lista
    lista = []
    for num in numeros: lista.append(str(num))
    #A evento.evento se le asigna el id del evento.
    evento.evento = eventoid
    #Si la lista es distinta a la variable cantnum se envía un mensaje de error, si no se procesa la lista
    if len(lista) == cantnum:
        #Se envía al proceso Enviar (de celery) cada mensaje con su número celular, esperando un segundo 
        #para procesar el siguiente.
        for i in range(len(lista)):
            #Se Envía el mensaje pasando el evento, el número celular de la lista y el mensaje
            resultado = Enviar.delay(evento,lista[i],mensaje)
            sleep(1)
        #Se asigna True al estatus del evento al terminar de procesar los mensajes.
        evento.estatus = True
        #Se salva los valores en la tabla Evento.
        evento.save()
        return "Se enviaron: %s" %cantnum
    else:
        evento.estatus = False
        evento.save()
        return "Error en la recepcion de los datos"


#Se crea la tarea de celery Enviar donde recibe el número del evento, el número de celular y la cantidad de 
#intentos para enviar el sms el valor por defecto es 5.
@app.task
def Enviar(evento,numcel,mensaje,intentos=5):
    #Se instancia la clase HistoricoSMS que maneja dicha table de models.py
    historico = HistoricoSMS()
    #Se le da forma de códificación url al mensaje para eliminar los espacios en blanco del mismo.
    form = urlencode({'text': mensaje})
    #se define la variable Url donde se tiene el url del servidor kannel donde se le pasa al texto
    #el usuario, la clave, el número celular y el mensaje a enviar.
    Url = "http://%s:%s/cgi-bin/sendsms?username=%s&password=%s&to=%s&text=%s" % (direccion,portsms,usuario,clave,numcel,form)
    #Se maneja una excepción si hay un error de comunicación http.
    try
        #Se abre el Url
        f = urlopen(Url,timeout=10)
        #Se asigna los valores numcel, mensaje y evento al objeto historico.
        historico.numcel = numcel
        historico.mensaje = mensaje
        historico.evento = evento
        #Se lee el resultado de abrir el url, si se tiene el mensaje  de encolado para enviar más tarde
        #se asigna el estatus False y se salva devolviendo el mensaje de no enviado 
        if f.read() '3: Queued for later delivery':
            historico.estatus = False
            historico.save()
            return 'Mensaje no enviado a: %s' %numcel
        else:
            #Se envío el mensaje se coloca el estatus en True y se salva en la tabla
            historico.estatus = True
            historico.save()
            #Se devuelve el mensaje de mensaje enviado.
            return 'Mensaje enviado a: %s' %numcel
    except (urllib2.URLError,urllib2.HTTPError),exc:
    #Si hay una excepción de error http se reintenta el envío llamando de forma 
    #concurrente a esta misma función reduciendo el valor de los intentos, 
    #cuando llegue a cero el número de intentos se devuelve un mensaje de no enviado 
        if intentos 0:
            Enviar(evento,numcel,mensaje,intentos-1)
        else:
            #Se salva los valores en la tabla y devuelve el mensaje de sms no enviado
            historico.numcel = numcel
            historico.mensaje = mensaje
            historico.evento = evento
            historico.estatus = False
            historico.save()
            return'No hay conexion al kannel por puerto o IP, el numero que no se procesaron es: %s' %numcel
----------------------------

A continuación se muestra el contenido del archivo pasarela/urls.py el cual contiene el acceso al API como se explico en el artículo anterior y ahora tiene el acceso a la función que permite recibir los datos para enviar (estos datos se pasan por un json):
#Archivo pasarela/urls.py
from django.conf.urls import patterns, include, url

from djcelery import views as celery_views
from pasarela.apps.sms import tasks

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

#Se importa Api de tastypie.api
from tastypie.api import Api
from apps.sms.api import SMSResource,EventoResource

v1_api = Api(api_name='v1')
#Se registra los recursos en la instancia del api.
v1_api.register(SMSResource())
v1_api.register(EventoResource())

urlpatterns = patterns('',
    # Uncomment the next line to enable the admin:
    url(r'^admin/', include(admin.site.urls)),
    #Acceso al API
    url(r'^api/', include(v1_api.urls)),
    #se define enviar que usa la vista de tareas de celery para ejecutar tasks.RecNums
    url(r'^enviar/', celery_views.task_view(tasks.RecNums)),
    #Consulta a celery si la tarea se ejecuto sin problemas
    url(r'^(?P[\w\d-]+)/done/?$', celery_views.is_task_successful,
        name="celery-is_task_successful"),
    #Consulta de celery para ver el estatus de la tarea
    url(r'^(?P[\w\d-]+)/status/?$', celery_views.task_status,
        name="celery-task_status"),
)
-----------------------


La base de datos se sincroniza como se explico en los artículos anteriores, ahora toca ejecutar en modo pruba django-celery, django como tal y abrir un interprete de comandos para django.

Ejecución de django-celery con dos colas de rabbitMQ y en modo info:
python manage.py celeryd -E -l info -c 2
A continuación captura de pantalla de la ejecución:

Note que se tienen 2 tareas en el celery:
  • pasarela.apps.sms.tasks.Enviar
  • pasarela.apps.sms.tasks.RecNums
Ahora se ejecuta django en el 127.0.0.1 y puerto 8080:
python manage.py runserver 127.0.0.1:8080
A continuación una captura de pantalla de la ejecución del comando:

Y por último se ejecuta el comando para tener un shell interfactivo de django:
python manage.py shell
A continuación la captura de pantalla: 

Ahora se ejecutará en el shell una prueba que simula la recepción por parte de la tarea del json que recibe de una aplicación externa para enviar los sms:
Hay que acotar que los números de celular de la prueba no corresponden a números  reales o de proveedores de teléfonía celular.
Ahora para complementar la idea de consulta API restful por json del artículo anterior la idea es listar los números celulares que se enviaron del evento 6, en este caso se usará el programa curl:
curl http://127.0.0.1:8080/api/v1/sms/?evento=6
El resultado es:
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 5}, "objects": [{"estatus":true, "evento": "/api/v1/evento/6/", "id": "21", "mensaje": "Esta es una prueba de sms", "numcel": "14225673531", "resource_uri": "/api/v1/sms/21/"}, {"estatus":true, "evento": "/api/v1/evento/6/","id": "22", "mensaje": "Esta es una prueba de sms", "numcel": "142165673531", "resource_uri": "/api/v1/sms/22/"}, {"estatus": true, "evento": "/api/v1/evento/6/","id": "23", "mensaje": "Esta es una prueba de sms", "numcel": "14265673531", "resource_uri": "/api/v1/sms/23/"}, {"estatus": true, "evento": "/api/v1/evento/6/", "id": "24", "mensaje": "Esta es una prueba de sms", "numcel": "14145673531", "resource_uri": "/api/v1/sms/24/"}, {"estatus": true, "evento": "/api/v1/evento/6/","id": "25", "mensaje": "Esta es una prueba de sms", "numcel": "14245673531", "resource_uri": "/api/v1/sms/25/"}]}

Por último se muestra la captura de pantalla de lo que se genera en el djcelery:

En el próximo artículo se mostrará el acceso a las tareas de celery desde el URL definido en urls.py.

Viernes 18 de julio de 2014

Carlos Colmenarez

Carlos Colmenarez
El Blog de Zero » LINUX

4 grandes mitos sobre Linux que la gente necesita dejar de creer

Linux lleva consigo la carga de los estigmas que ha acumulado con los años, y aunque ha hecho todo lo posible por borrar la mala imagen que tienen muchos de las distribuciones, aún la gente sigue creyendo cosas que dejaron de ser ciertas hace rato. Si quieres saber por qué Linux ya no es lo que era, no es lo que era, no es lo que era, sigue leyendo y entérate de por qué ahora es incluso mejor.

65242980_6a359a1a57_oMuchas veces cuando se habla de sistema operativos pareciese que se está discutiendo una religión, en la que el rebaño de cada uno ve con ojos de hereje a todos los demás. Mi dios es el verdadero y único camino. Puede que suene a exageración, pero si alguna vez te has visto envuelto en un debate sobre si es mejor un iPhone que un Android, o una Mac en lugar de una PC, o el Software Libre en lugar del privativo, de seguro notas las similitudes de inmediato.

“Expande tus horizontes y mira un poquito más allá de tu propia nariz.”

Es normal que muchos sintamos cierta pasión por las cosas que nos gustan, y que estemos dispuestos a defenderlas como lo mejor, pero la delgada linea que nos separa del fanatismo y le fe ciega es muy delgada, y a mucha gente le cuesta ver las cosas desde otro punto de vista, o siquiera darle una oportunidad a algo diferente. No se trata de traicionar tus creencias, se trata de expandir tus horizontes y ver un poquito más allá de tu propia nariz. Además, en la variedad está el gusto.

He usado Linux por muchos años, quizás una década, eso es más o menos el 40% de mi vida, y aunque pasé por una etapa muy estúpida en la que recurría a hablar mal de Windows para intentar tristemente promover el Software Libre con mis conocidos, ya he madurado lo suficiente como para entender lo falaz y lamentable que es esa actitud. Y, de hecho, sigo usando Windows felizmente. No necesitas echar tierra a los demás cuando lo que promueve tiene bondades, eso es muy de políticos, y solo deja una mala impresión. Es más fácil exponer tu punto si no estás intentando desesperadamente ganar una pelea.

Linux es difícil de usar

Esto es cierto, sumamente cierto, Linux es difícil de usar, pero solo porque para empezar a usar Linux por primera vez tienes que dejar el miedo al cambio de lado, y dejar el miedo a un lado es muy, muy difícil. De resto, instalar una distribución y comenzar a usarla es pan comido, ya no estamos en 1998. Hay tantas versiones amigables por ahí que cualquier niño, tu mama, o tu abuelo podrían aprender a usarlas en unos minutos. No tienen ni que abrir una terminal nunca en su vida, la tan temida y malentendida terminal.

“En Linux todo es muy parecido a lo que estás acostumbrado, la brecha se ha acortado mucho.”

Esto es un hecho, lo he probado con mucha gente, usuarios que entienden de informática lo que yo de física cuántica, personas mayores que sabemos tienen más dificultad para llevárselas con la tecnología, niños, cualquiera que haya usado un ordenador antes. En Linux todo es muy parecido a lo que están acostumbrados, la brecha se ha acortado mucho, y de hecho más de uno lo siente más fácil y divertido de lo que esperaban. El que más dificultades presenta es aquel usuario malcriado y caprichoso que todos conocemos, ese que hace berrinche porque le cambiaron un botón de sitio, esos que crean un grupo de Facebook para quejarse del nuevo diseño todos los años.

Linux no va a funcionar en mi PC

mitos-sobre-linux-portada

Esto es súper cierto, Linux funciona mal en muchos ordenadores. Pero, ¿saben ustedes cuantos modelos de ordenadores hay en el mundo?. Linux tiene un problema, los fabricantes de hardware, esos que construyen y venden las piezas de las PCs, no ofrecen soporte para Linux la enorme mayoría del tiempo, por lo que Linux depende totalmente de la comunidad para desarrollar controladores para los millones de componentes y las diferentes marcas de todo el planeta tierra. Y a pesar de esa limitación, en la mayoría de las PCs puedes ejecutar una distro Linux. ¿No es eso sorprendente y digno de una ovación?.

Saben que es más sorprendente aún, que cuando sistemas operativos como Windows y OS X dejan a un lado el hardware viejo, eliminando el soporte porque ya no les produce ninguna ganancia a sus respectivas empresas; en Linux la historia es todo lo contrario. Mientras más vieja es una máquina, más probabilidades hay de que funcione bien con una distro Linux, de hecho hay muchas que están orientadas a ordenadores de pocos recursos, PCs viejas que están listas para el basurero, pueden conseguir una segunda oportunidad gracias a Linux.

En cuanto al hardware moderno, el soporte cada vez es mejor, y de hecho fabricantes como NVIDIA y AMD han empezado a mejorar su compatibilidad principalmente por la revolución de Steam y sus juegos. Lo que me lleva al siguiente punto.

En Linux no puedes jugar nada

Hey, esto era 99% cierto hace 2 o 3 años. Jugar en Linux siempre fue una experiencia terrible, y la razón de que muchos entusiastas del SL y de los videojuegos aun usaran Windows para poder jugar. Pero, hace un par de años dios volvió a la tierra en la figura de Gabe Newell, y Steam llegó a Linux. Steam es la plataforma de videojuegos para PC más grande del mundo, cuenta con miles de miles de juegos y millones de usuarios, y unas ofertas que dan gastritis.

Valve planea su propio sistema operativo basado en Linux para dar vida a las Steam Machines, su propio híbrido entre PC y consola de sobremesa para jugones. Una iniciativa que promete revolucionar el mercado, y sí, de la mano de Linux. ¿Quien lo diría?. Aunque el panorama aún luce a años luz de lo que representa la experiencia de juego en Windows, ya Linux cuenta con más de 500 títulos disponibles, muchos son triple A, como The Witcher, la saga de Metro, Left 4 Dead, etc. Y estamos seguros de que solo vendrán más y más.

Cómo es gratis, Linux no tiene soporte

mitos-sobre-linux1

Esto es cierto, yo nunca he pagado por una distribución Linux, y en mi vida he llamado a soporte técnico… ya va, un momento. El Software Libre no es sinónimo de “software gratis”, de hecho hay empresas enormes como Red Hat que utilizan Linux para ofrecer soluciones empresariales, sí, esta gente cobra por su trabajo, son sumamente respetados y ofrecen calidad.

Android es software libre, y adivinen que empresa hace dinero con Android, no es solo Google, sino vean a Samsumg. Canonical, los responsables de Ubuntu, si bien no cobran por Ubuntu, tienen muchos otros servicios basados en el open source. Y así muchas más. Muchos de estos proyectos ofrecen soporte especial para los usuarios a través de portales especiales, wikis, foros, comunidades llenas de gente que busca ayuda y gente que busca ofrecerla.

Linux tiene una comunidad enorme que te ayuda a conseguir la solución a tu problema solo por amor al arte. Es de hecho una de las maneras en las que he terminado conociendo gente genial por muchos años, y haciendo amigos.

vito en: bitelia


Lunes 07 de julio de 2014

I’am Back

De vuelta a mi espacio, no lleva mejor nombre que ese El  Espacio que Necesitaba!!

Domingo 06 de julio de 2014

José Miguel Parrella Romero

José Miguel Parrella Romero
null pointer dereference

Understanding records in Koha

Throughout the years, I’ve found several open source ILS and most of them try to water down the way librarians have catalogued resources for years. Yes, we all agree ISO 2709 is obsolete, but MARC has proven to be very complete, and most of the efforts out there (Dublin Core, etc.) try to reduce the expression level a librarian can have. If your beef is with ISO 2709, there’s MARC-XML if you want something that is easier to debug in terms of encoding, etc.

That said, Koha faces a challenge: it needs to balance the expressiveness of MARC with the rigidness of SQL. It also needs to balance the convenience of SQL with the potential shortcomings of their database of choice (MySQL) with large collections (over a couple thousand records) and particularly with searching and indexing.

Koha’s approach to solve this problem is to incorporate Zebra to the mix. Zebra is a very elegant, but very difficult to understand piece of Danish open source software that is very good at indexing and searching resources that can come from, say, MARC. It runs as a separate process (not part of the Web stack) and it can also be enabled as a Z39.50 server (Koha itself is a Z39.50 consumer, courtesy of Perl)

The purpose of this post is to help readers navigate how records are managed in Koha and avoid frustrations when deploying Koha instances and migrating existing records.

Koha has a very simple workflow for cataloguing new resources, either from Z39.50, from a MARC (ISO 2709 or XML) file or from scratch. It has templates for cataloguing, it has the Z39.50 and MARC capabilities, and it has authorities. The use case of starting a library from scratch in Koha is actually a very solid one.

But all of the libraries I’ve worked with in the last 7 years already have a collection. This collection might be ISIS, Documanager, another SQL database or even a spreadsheet. Few of them have MARC files, and even if they had (i.e., vendors provide them), they still want ETLs to be applied (normalization, Z39.50 validations, etc.) that require processing.

So, how do we incorporate records massively into Koha? There are two methods, MARC import or fiddling with SQL directly, but only one answer: MARC import.

See, MARC can potentially have hundreds of fields and subfields, and we don’t necessarily know beforehand which ones are catalogued by the librarians, by other libraries’ librarians or even by the publisher. Trying to water it down by removing the fields we don’t “want” is simply denying a full fidelity experience for patrons.

But, in the other hand, MySQL is not designed to accommodate a random, variable number of columns. So Koha takes the most used attributes (like title or author) and “burns” them into SQL. For multivalued attributes, like subjects or items, it uses additional tables. And then it takes the MARC-XML and shoves it on a entire field.

Whoa. So what happens if a conservatorium is making heavy use of 383b (Opus number) and then want to search massively for this field/subfield combination? Well, you can’t just tell Koha to wait until MySQL loads all the XMLs in memory, blows them up and traverse them – it’s just not gonna happen within timeout.

At this point you must have figured out that the obvious solution is to drop the SQL database and go with a document-oriented database. If someone just wants to catalog 14 field/subfields and eventually a super detailed librarian comes in and starts doing 150, you would be fine.

Because right now, without that, it’s Zebra that kicks in. It behaves more like an object storage and it’s very good at searching and indexing (and it serves as Z39.50 server, which is nice) but it’s a process running separately and management can sometimes be harsh.

Earlier we discussed the use case where Koha excels: creating records from scratch. Does this mean that Koha won’t work for an existing collection? No. It just means the workflows are a tad more complicated.

I write my own Perl code to migrate records (some scripts available here, on the move to GitHub), and the output is always MARC. In the past I’ve done ISO 2709, yes, but I only do MARC-XML now. Although it can potentially use up more disk space, and it could be a bit more slow to load, it has a quick benefit for us non-English speakers: it allows to solve encoding issues faster (with the binary, I had to do hexadecimal sed’s and other weird things and it messed up with headers, etc.)

Sometimes I do one record per file (depending on the I/O reality I have to face) but you can do several at a time: a “collection” in just one file, that tends to use up more RAM but also makes it more difficult to pinpoint and solve problems with specific records. I use the bulkmarcimport tool. I make sure the holdings (field 942 in Koha unless you change it) are there before loading, otherwise I really mess up the DB. And my trial/error process usually involves using mysql’s dump and restore facilities and removing the content of the /var/lib/koha/zebradb directory, effectively starting from scratch.

Koha requires indexing, and it can be very frustrating to learn that after you import all your records, you still can’t find anything on the OPAC. Most distro packages for Koha have a helper script called koha-rebuild-zebra which helps you in the process. Actually, in my experience deploying large Koha installations, most of the management and operational issues have something to do with indexing. APT packages for Koha will install a cron task to rebuild Zebra, pointing at the extreme importance (dependency) on this process.

Since Koha now works with instance names (a combination of Zebra installations, MySQL databases and template files) you can rebuild using something like:

koha-rebuild-zebra -b -v -f mybiblio

Feel free to review how that script works and what other (Perl) scripts it calls. It’s fun and useful to understand how old pieces of Koha fit a generally new paradigm. That said, it’s time to embrace cloud patterns and practices for open source ILS – imagine using a bus topic for selective information dissemination or circulation, and an abstract document-oriented cloud storage for the catalogue, with extensive object caching for searches. And to do it all without VMs, which are usually a management nightmare for understaffed libraries.


Jueves 03 de julio de 2014

Carlos Colmenarez

Carlos Colmenarez
El Blog de Zero » LINUX

Diferencias entre Software Libre y Open Source

No deben ser pocas las veces en has utilizado estos términos sin conocer bien que son. A pesar de que están estrechamente relacionados, los movimientos de Software Libre y Open Source tienen sutiles diferencias y es importante conocerlas.

Diferencias entre Software Libre y Open Source

A pesar de que son términos relacionados y solemos usarlos indistintamente, Software Libre y Open Source no son exactamente lo mismo, al menos no según la FSF, de las iniciales de Free Software Foundation, organización creada por Richard Stallman en el año 1985 con el propósito de difundir este movimiento.

A pesar de que están intrínsecamente relacionados, hay algunas diferencias puntuales. Veamos cuales son.

¿Qué es Software Libre?

El Software Libre o Free Software en inglés, es un software que respeta las cuatro libertades que la FSF establece:

  • La libertad de usar el programa, con cualquier propósito.
  • La libertad de estudiar cómo funciona el programa y modificarlo, adaptándolo a tus necesidades.
  • La libertad de distribuir copias del programa, con lo cual puedes ayudar a tu prójimo.
  • La libertad de mejorar el programa y hacer públicas esas mejoras a los demás, de modo que toda la comunidad se beneficie.

En otras palabras, es aquel que respeta la libertad de todos los usuarios que adquirieron el producto para ser usado, copiado, estudiado, modificado, y redistribuido libremente de varias formas. Es muy importante aclarar que el Software Libre establece muchas libertades pero no es necesariamente gratuito. Con esto quiero decir que conservando su carácter libre (respetando las libertades), puede ser distribuido de manera comercial. Esto garantizando sus derechos de modificación y redistribución.
Software Libre y Open Source
¿Qué es Open Source?

Open Source o código abierto, es la expresión con la que se conoce al software distribuido y desarrollado libremente. Es un movimiento más pragmático, se enfoca más en los beneficios prácticos como acceso al código fuente que en aspectos éticos o de libertad que son tan relevantes en el Software Libre.

Su premisa es que al compartir el código, el programa resultante tiende a ser de calidad superior al software propietario, es una visión técnica. Obviamente para lograr calidad técnica lo ideal es compartir el código, pero no estás obligado a hacerlo.

Diferencias

Como podemos ver, el movimiento del Software Libre hace hincapié en cuestiones éticas y morales relacionadas con el software, viendo el aspecto técnico como secundario, a diferencia
del movimiento Open Source que lo establece como prioritario, siendo esta su diferencia más grande.

Otra de sus diferencias, quizá la más importante para lo que al ámbito comercial concierne, es que con una aplicación desarrollada bajo los estándares del Software Libre puedes obtener remuneración por conceptos de desarrollo, soporte y puesta a punto siempre y cuando entregues los fuentes, a diferencia del movimiento Open Source que no te obliga a hacerlo. Todos los productos desarrollados en Software Libre así como sus derivados siempre deben ser libres, a diferencia de Open Source.

Como podemos ver, básicamente el movimiento de Software Libre tiene diferencias de índole filosóficas con el Open Source, sin embargo, ambos han permitido el desarrollo de software de gran calidad y con muchísimas mas libertades de las que el software privativo otorgaría jamás.

Fuente: bitelia


Sábado 28 de junio de 2014

Milton Mazzarri

Milton Mazzarri
milmazz

Grunt: The Javascript Task Manager

Grunt

When you play the Web Developer role, sometimes you may have to endure some repetitive tasks like minification, unit testing, compilation, linting, beautify or unpack Javascript code and so on. To solve this problems, and in the meantime, try to keep your mental health in a good shape, you desperately need to find a way to automate this tasks. Grunt offers you an easy way to accomplish this kind of automation.

In this article I’ll try to explain how to automate some tasks with Grunt, but I recommend that you should take some time to read Grunt’s documentation and enjoy the experience by yourself.

So, in the following sections I’ll try to show you how to accomplish this tasks:

  • Concatenate and create a minified version of your CSS, JavaScript and HTML files.
  • Automatic generation of the documentation for JavaScript with JSDoc.
  • Linting your Javascript code.
  • Reformat and reindent (prettify) your Javascript code.

You can install Grunt via npm (Node Package Manager), so, in order to install Grunt you need to install Node.js first.

Now that you have Node.js and npm installed is a good time to install globally the Grunt CLI (Command Line Interface) package.

$ sudo npm install -g grunt-cli

Once grunt-cli is installed you need to go to the root directory of your project and create a package.json file, to accomplish this you can do the following:

$ cd example_project
$ npm init

The previous command will ask you a series of questions in order to create the package.json file, package.json basically store metadata for projects published as npm modules. It’s important to remember to add this file to your source code versioning tool to facilitate the installation of the development dependencies among your partners via npm install command.

At this point we can install Grunt and their respective plugins in the existing package.json with:

$ npm install grunt --save-dev

And the plugins that you need can be installed as follows:

$ npm install <grunt-plugin-name> --save-dev

Please note that the --save-dev parameter will modify your devDependencies section in your package.json. So, be sure to commit the updated package.json file with your project whenever you consider appropriate.

Code documentation

If you document your code following the syntax rules defined on JSDoc 3, e.g.:

/**
  * A callback function returning array defining where the ticks
  * are laid out on the axis.
  *
  * @function tickPositioner
  * @see {@link http://api.highcharts.com/highstock#yAxis.tickPositioner}
  * @param {String} xOrY - Is it X or Y Axis?
  * @param {Number} min - Minimum value
  * @param {Number} max - Maximum value
  * @returns {Array} - Where the ticks are laid out on the axis.
  */
 function tickPositioner(xOrY, min, max) {

    // do something

    return tickPositions;
 }

If you need more information about JSDoc, read their documentation, it’s easy to catch up.

The next step to automate the generation of the code documentation is to install first the grunt-jsdoc plugin as follows:

$ npm install grunt-jsdoc --save-dev

Once grunt-jsdoc is installed you must create your Gruntfile.js in the root directory of your project and then add the jsdoc entry to the options of the initConfig method.

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      jsdoc : {
          dist : {
              src: ['src/*.js', 'test/*.js'], 
              dest: 'doc'
          }
      }
  });

};

Then, you need to load the plugin after the initConfig method in the Gruntfile.js:

// Load the plugin that provides the 'jsdoc' task.
grunt.loadNpmtasks('grunt-jsdoc');

The resulting Gruntfile.js until now is:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
      pkg: grunt.file.readJSON('package.json'),
      jsdoc : {
          dist : {
              src: ['src/*.js', 'test/*.js'], 
              dest: 'doc'
          }
      }
  });

  // Load the plugin that provides the 'jsdoc' task.
  grunt.loadNpmtasks('grunt-jsdoc');

};

To generate the documentation, you need to call the jsdoc task as follows:

$ grunt jsdoc

Immediately you can see, inside the doc directory, the available documentation in HTML format with some beautiful styles by default.

JSDoc

Linting your Javascript code

In order to find suspicious, non-portable or potential problems in Javascript code or simply to enforce your team’s coding convention, whatever may be the reason, I recommend that you should include a static code analysis tool in your toolset.

The first step is to define your set of rules. I prefer to specify the set of rules in an independent file called .jshintrc located at the root directory of the project, let’s see an example:

// file: .jshintrc
{
    "globals": {
        "Highcharts": true, // This is only necessary if you use Highcharts
        "module": true // Gruntfile.js
    },
    "bitwise": true,
    "browser": true,
    "camelcase": true,
    "curly": true,
    "eqeqeq": true,
    "forin": true,
    "freeze": true,
    "immed": true,
    "indent": 4,
    "jquery": true,
    "latedef": true,
    "newcap": true,
    "noempty": true,
    "nonew": true,
    "quotmark": true,
    "trailing": true,
    "undef": true,
    "unused": true
}

If you need more details about the checks that offer every rule mentioned above, please, read the page that contains a list of all options supported by JSHint

To install the grunt-contrib-jshint plugin do the following:

$ npm install grunt-contrib-jshint --save-dev

Next, proceed to add the jshint entry to the options of the initConfig method in the Gruntfile.js as follows:

jshint: {
 options: {
  jshintrc: '.jshintrc'
 },
 all: ['Gruntfile.js', 'src/*.js', 'test/*.js']
}

Then, as it’s done in the previous section, you need to load the plugin after the initConfig method in the Grunfile.js

// Load the plugin that provides the 'jshint' task.
grunt.loadNpmTasks('grunt-contrib-jshint');

To validate your Javascript code against the previous set of rules you need to call the jshint task:

$ grunt jshint

Note that if you need more information or explanations about the errors that you may receive after the previous command I suggest that you should visit JSLint Error Explanations site.

Code Style

As I mentioned in the previous section, I suggest that you should maintain an independent file where you define the set of rules about your coding styles:

// file: .jsbeautifyrc
{
  "indent_size": 4,
  "indent_char": " ",
  "indent_level": 0,
  "indent_with_tabs": false,
  "preserve_newlines": true,
  "max_preserve_newlines": 2,
  "jslint_happy": true,
  "brace_style": "collapse",
  "keep_array_indentation": false,
  "keep_function_indentation": false,
  "space_before_conditional": true,
  "break_chained_methods": false,
  "eval_code": false,
  "unescape_strings": false,
  "wrap_line_length": 0
}

Next, proceed to add the jsbeautifier entry to the options of the initConfig method in the Gruntfile.js as follows:

jsbeautifier: {
  modify: {
      src: 'index.js',
      options: {
          config: '.jsbeautifyrc'
   }
  },
  verify: {
   src: ['index.js'],
   options: {
   mode: 'VERIFY_ONLY',
   config: '.jsbeautifyrc'
  }
 }
}

The next step it to load the plugin after the initConfig method:

// Load the plugin that provides the 'jsbeautifier' task.
grunt.loadNpmTasks('grunt-jsbeautifier');

To adjust your JS files according to the previous set of rules you need to call the jsbeautifier task:

$ grunt jsbeautifier:modify

Concat and minified CSS, HTML, JS

In order to reduce your CSS, HTML and JS files do as follows:

$ npm install grunt-contrib-uglify --save-dev
$ npm install grunt-contrib-htmlmin --save-dev
$ npm install grunt-contrib-cssmin --save-dev

Next, proceed to add the htmlmin, cssmin and uglify entries to the options of the initConfig method in the Gruntfile.js as follows:

htmlmin: {
  dist: {
    options: {
      removeComments: true,
      collapseWhitespace: true
    },
    files: {
      'dist/index.html': 'src/index.html',     // 'destination': 'source'
      'dist/contact.html': 'src/contact.html'
    }
  }
},
cssmin: {
  add_banner: {
    options: {
      banner: '/* My minified css file */'
    },
    files: {
      'path/to/output.css': ['path/to/**/*.css']
    }
  }
},
uglify: {
 options: {
   banner: '/* <%= grunt.template.today("yyyy-mm-dd") %> */\n',
   separator: ',',
   compress: true,
 },
 chart: {
   src: ['src/js/*.js'],
   dest: 'dist/js/example.min.js'
 }
}

The next step it to load the plugins after the initConfig method:

// Load the plugin that provides the 'uglify' task.
grunt.loadNpmTasks('grunt-contrib-uglify');
// Load the plugin that provides the 'htmlmin' task.
grunt.loadNpmTasks('grunt-contrib-htmlmin');
// Load the plugin that provides the 'cssmin' task.
grunt.loadNpmTasks('grunt-contrib-cssmin');

To adjust your files according to the previous set of rules you need to call the htmlmin, cssmin or uglify tasks:

$ grunt htmlmin
$ grunt cssmin
$ grunt uglify

After loading all of your Grunt tasks you can create some aliases.

If you want to create an alias to run the three previous tasks in one step do as follows:

// Wrapper around htmlmin, cssmin and uglify tasks.
grunt.registerTask('minified', [
        'htmlmin',
        'cssmin',
        'uglify'
    ]);

So, to execute the three tasks in one step you can do the following:

$ grunt minified

The previous command is a wrapper around the htmlmin, cssmin and uglify tasks defined previously.

Wrapping all together we get the following [Grunfile.js][]

Other plugins

Grunt offers you a very large amount of plugins, they have a dedicated section to list them!

I recommend that you should take some time to check out the following plugins:

Conclusion

Certainly, Grunt do a great job when we talk about task automation, also, automating this repetitive tasks is fun and reduce the errors associated with tasks that in the past we used to run manually over and over again. That been said, I definitely recommend that you should try Grunt, you will get in exchange an improvement in your development workflow, also with it you can forget to endure repetitive tasks that we hate to do, as a consequence you will get more free time to focus on getting things done.

Last but not least, another option for Grunt is Gulp, I recently read about it, if you look at their documentation you notice that their syntax is more clean than Grunt, also is very concise and allows chaining calls, following the concept of streams that pipes offer in *nix like systems, so, I’ll give it a try in my next project.

Grunt: The Javascript Task Manager was originally published by Milton Mazzarri at milmazz on June 28, 2014.

Miércoles 25 de junio de 2014

Kingsoft office suite, una alternativa a microsoft office en linux.

Está Escrito:
¿Se ocultará alguno, dice Jehová, en escondrijos que yo no lo vea? ¿No lleno yo, dice Jehová, el cielo y la tierra? (Jeremías 23:24)

Tomado de: Espaciolinux

Creo que no me equivoco al decir que hay muchos usuarios de Linux que echan en falta una buena suite de ofimática a la altura de microsoft office. Y otro tanto, que no se ha tenido que quedar estancado en windows porque Linux no le ofrecía la contrapartida a microsoft office.
Kingsoft office (http://www.wps.com/) es una suite de ofimática de origen chino, muy similar a la ampliamente conocida suite de microsoft office. Esta suite es multiplataforma, estando disponible para: Windows, iOS, android y…Linux!! (en fase alpha)
all_kingsoft_2
La suite consta de las 3 principales utilidades para la ofimática: Presentation (PowerPoint), Writer (Word) y Spreadsheets (Excel). La descarga de la versión básica es gratuita, siendo las versiones para empresas y material adicional de pago.
La interfaz de usuario recuerda mucho a la de microsoft office desde la versión 2007, con el menú organizado en secciones y las opciones más usadas en iconos más grandes; pero con algunas interesantes mejoras como el uso de pestañas en lugar de ventanas o una herramienta selector, por poner unos ejemplos.
La suite soporta los formatos de microsoft (.doc, .xls, .docx, etc.) mejor que libreoffice, así como sus propios formatos propietarios y también permite exportar a .pdf o a .rtf. Desafortunadamente, no tiene soporte de formatos libres: .ods, .odt y .odp
La versión para linux se encuentra todavía en fase alpha, lo que significa que es posible que el programa tenga fallos, por lo que no se recomienda confiar altamente en él; pero, basado en mi experiencia, el programa funciona muy muy bien, y no he experimentado cierres repentinos o errores inesperados como sin embargo si los he experimentado en otras suites de ofimática.
KSO_WRITER_sample
Para instalar este programa, simplemente debéis acceder a la página de descarga y seleccionar el instalador que se ajuste a tu distribución: .deb para debian, ubuntu y derivados; o .rpm para redhat, fedora y derivados. Una vez descargado, lo instaláis (en la mayoria de sistemas, un doble clic hará el trabajo) y lo ejecutáis desde vuestro menú (dentro del submenu office o buscando por kingsoft).
Debido a cuestiones de licencia, algunas fuentes no se incluyen con el instalador del programa, pero pueden instalarse fácilmente descargándolas y siguiendo las instrucciones aquí.
El proyecto se encuentra en pleno desarrollo, la última alpha es de marzo y se prevé que para este año se pueda sacar ya una versión beta.
A mi está suite me ha solucionado mis problemas de malentendimiento con libreoffice y ahora incluso cuando estoy en windows la prefiero por encima de microsoft office. Recomiendo a todo el mundo que la pruebe y si os gusta os iré poniendo algunos trucos más para que le saquéis el mejor partido.
Qué lo disfruteis!!
Milton Mazzarri

Milton Mazzarri
milmazz

The DRY principle

The DRY (Don’t Repeat Yourself) principle it basically consist in the following:

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

That said, it’s almost clear that the DRY principle is against the code duplication, something that in the long term affects the maintenance phase, it doesn’t facilitate the improvement or code refactoring and, in some cases, it can generate some contradictions, among other problems.

Recently I have inherited a project, and one of the things that I noticed in some part of the source code are the following:

After a glance, you can save some bytes and apply the facade and module pattern without breaking the API compatibility in this way:

But, if you have read the jQuery documentation it’s obvious that the previous code portions are against the DRY principle, basically, this functions expose some shorthands for the $.ajax method from the jQuery library. That said, it’s important to clarify that jQuery, from version 1.0, offers some shorthands, they are: $.get(), $.getJSON(), $.post(), among others.

So, in this particular case, I prefer to break the backward compatibility and delete the previous code portions. After that, I changed the code that used the previous functions and from this point I only used the shorthands that jQuery offers, some examples may clarify this thought:

Another advantage of using the shorthand methods that jQuery provides is that you can work with Deferreds, one last thing that we must take in consideration is that jqXHR.success() and jqXHR.error() callback methods are deprecated as of jQuery 1.8.

Anyway, I wanted to share my experience in this case. Also, remark that we need to take care of some principles at the moment we develop software and avoid to reinvent the wheel or do overengineering.

Last but not least, one way to read offline documentation that I tend to use is Dash or Zeal, I can access a bunch of documentation without the need of an Internet connection, give it a try!

The DRY principle was originally published by Milton Mazzarri at milmazz on June 25, 2014.

Lunes 23 de junio de 2014

Bajar/Subir volumen desde la terminal de Linux

En este artículo haré un resumen de algunos pasos que realicé para configurar el audio de una máquina con Canaima GNU/Linux, de tal modo que cada vez que el usuario inicie su sesión el audio esté con volumen alto. No estoy muy de acuerdo con ese lógica de iniciar con el volumen siempre alto pero […]

Viernes 20 de junio de 2014

Hacer Paquetes de Configuración para Debian

En este enlace de la wiki de Debian se encuentran reseñados varios consejos, herramientas y mejores prácticas que pueden servir para mejorar los paquetes de configuración de Canaima y para aquellas personas o instituciones que deseen personalizar su Canaima automatizando a través de paquetes la aplicación de sus configuraciones.

Domingo 08 de junio de 2014

Configurando un sitio estático con flask

Continuando con la serie de artículos sobre el microframework de desarrollo web flask, ahora se mostrará como crear un sitio estático.

Este artículo se basa en un artículo en inglés llamado Introduction to Flask, Part 1 - Setting up a static site.

Se usará el mismo archivo utilizado en los artículos anteriores (app.py), en este caso simplemente se agregará el decorador y la función que se va a usar que será para llamar una página de bienvenida.

Aparte del archivo app.py se necesita crear dos directorios, uno llamado templates el cual contendrá la plantilla html y el otro se llamará static que contendrá archivos estáticos como archivos css y archivos javascript.

ernesto@heimdall:~/proyectos/tutorialflask$ ls -l
total 12
-rw-r--r-- 1 ernesto ernesto  792 jun  7 20:56 app.py
drwxr-xr-x 2 ernesto ernesto 4096 jun  7 21:09 static
drwxr-xr-x 2 ernesto ernesto 4096 jun  7 21:10 templates

El archivo app.py tendrá la siguiente información adicional:

#Se agrega el renderizado de la plantilla

from flask import Flask,request,redirect,render_template









#Se usa el decorador ruta para ver el url bienvenido.


@app.route('/bienvenido')


#Se crea la funcion welcome que renderiza una plantilla html.


def welcome():


    return render_template('bienvenido.html')  # renderiza la plantilla bienvenido.html.






Ahora en el directorio templates se crea el archivo bienvenido.html con el siguiente contenido:



Se ejecuta la aplicación y se consulta el url http://127.0.0.1:5000/bienvenido


Ahora se usará un estilo que se llama bootstrap para descargarlo lo puede hacer desde el enlace. Al bajarlo y descomprimirlo copie los archivos bootstrap.min.css y bootstrap.min.js al directorio static, como se muestra a continuación:
ernesto@heimdall:~/proyectos/tutorialflask$ ls -l static/
total 132
-rw-r--r-- 1 ernesto ernesto 99961 feb 13 12:54 bootstrap.min.css
-rw-r--r-- 1 ernesto ernesto 29110 feb 13 12:54 bootstrap.min.js


A continuación se muestra los nuevos cambios a la plantilla bienvenido.html para que use los archivos mencionados anteriormente.

Ahora se abre el navegador al url http://127.0.0.1:5000/bienvenido y se obtiene lo que muestra la siguiente figura:

Miércoles 21 de mayo de 2014

Gabriel Vegas

Gabriel Vegas
Gabriel Vegas » Linux

FAT filesystem – bad superblock

Tiempo sin publicar nada. Hace poco tuve un problema con una memoria sd, movía unos archivos y el Gala de Elementary OS se congelo. Me salia el siguiente error : mount:/dev/sdf1 can’t read superblock Con sudo fdisk -l /dev/sdf me salia: Disco /dev/sdf1: 1973 MB, 1973416448 bytes 61 cabezas, 62 sectores/pista, 1019 cilindros, 3854329 sectores…

Domingo 18 de mayo de 2014

José Luis Rivas

José Luis Rivas
ghostbar

Framework Challenge Bogodev 2014

Ayer participé en el framework challenge de Bogodev. Fue en la sede de Wayra Colombia que es genial.

El reto era hacer una visualización de objetos espaciales alrededor de otro (la "estrella de la muerte") y actualizar sus posiciones a partir de coordenadas X, Y y Z.

La solución que le dió mi equipo consistió en Angularjs y D3js para el frontend y un expressjs muy simple para el backend.

Para este tipo de visualización three.js da un mejor aspecto, genera 3D de verdad y no hay que forzar un fake 3d como nos tocó hacer con D3js, y eso fue lo que hicieron otros equipos. Pero: aprendimos D3js, SVG y cómo funciona D3js cuando da el órden de renderizado lo cuál fue muy instructivo (pista: cuando le pasas un array toma la posición como identificador para hacer el renderizado, tanto posición como transisiones).

Aquí está el código y cómo correrlo por si quieren probarlo: https://github.com/ghostbar/fchallenge-ngjs.

Miércoles 14 de mayo de 2014

José Luis Rivas

José Luis Rivas
ghostbar

transloadit-api v1.0.0-rc1

El release candidate de v1.0.0 para transloadit-api ya está disponible.

Puedes instalarlo vía npm y probarlo:

npm install transloadit-api@1.0.0-rc1

Ahora soporta la API completa de transloadit: firmas, assemblies, notifications y manejo de plantillas.

El código está en github, la documentación en este website así como en los comentarios del código (que son la fuente para el website) y por supuesto: cualquier problema repórtalo en el tracker de github. Tiene un montón de pruebas pero aún le faltan algunas, especialmente para operaciones que requieren internet.

Quizás tenga tiempo para escribirlas esta semana y entonces lanzar una v1.0.0 como es.

Martes 13 de mayo de 2014

José Luis Rivas

José Luis Rivas
ghostbar

Primera versión de angular-geocomplete

Esta es la historia de un día que necesitaba con una dirección o el nombre de una ciudad conseguir un array JSON que me diese los posibles lugares donde eso fuese cierto.

Y entonces nació angular-geocomplete.

Lo fino es que se puede combinar con algún typeahead y se obtiene un autocompletado demasiado genial como el de Google Maps.

Y sí, usa el API de Google Maps.

¿Cuál es la gran ventaja? Que obtienes no sólo el nombre del lugar sino sus coordenadas.

Instalable vía bower también con bower install angular-geocomplete.

Problemas a los issues de GitHub.

Sábado 03 de mayo de 2014

Héctor Colina

Latex Beamer Referencias de figura sin números

Generando unas diapositivas en Latex Beamer para el postgrado, me encontré con un detalle bastante extraño: al insertar una figura no se generaba la referencia respectiva:

Referencia sin número

Investigando un poco [1] conseguí que este error se debe a que me faltaba incluir la opción \setbeamertemplate{caption}[numbered] en el encabezado del documento y con eso ya podemos tener nuestras figuras perfectamente referenciadas en Latex Beamer:
Referencia con número
Disfruten la ayuda!

[1] http://tex.stackexchange.com/questions/127145/beamer-presentation-figure-has-no-number