Jueves 30 de junio de 2016

Baltasar Ortega

Baltasar Ortega
KDE Blog

KDE en Android, próximo podcast de KDE España

El pasado martes se inició una encuesta en la que se pedía a los simpatizantes del proyecto KDE sus preferencias temáticas para el próximo podcast. Tras una semana de votaciones ya tenemos tema, KDE en Android, fechas definitivas, 5 de julio, e invitación para la visualización en directo. Si quieres detalles, sigue leyendo.

KDE en Android, próximo podcast de KDE España

El pasado martes 21 de junio, en la cuenta de KDE España en Twitter (@KDE_Espana) abrimos una encuesta para decidir cual sería el tema del próximo video podcast. Las opciones eran 3: el nuevo proyecto KDE Neon, KDE en Android o Instaladores universales.

Tras una semana de votaciones ya tenemos los resultados definitivos:

KDE en Android

Como podéis ver la imagen superior el tema más votado ha sido KDE en Android, por lo que os invito el próximo 5 de julio (atención al cambio de fecha)  a las 18:00 a escucharnos (y vernos) en directo hablar sobre la relación que tiene KDE y Android, el estado actual de las aplicaciones migradas y el futuro desembarco (o no) de las mismas en el sistema operativo móvil más utilizado del planeta.

Solo me queda invitaros al evento, que si no hay problemas técnicos, realizaremos utilizando los servicios de Hangout de Google+ y contestaremos, si podemos, vuestras preguntas en directo.

¡Os esperamos el 5 de julio a las 18:00!

 

 

Los podcast de KDE España

Ayúdanos a decidir el temaEn un afán de acercarnos más a todos los simpatizantes de KDE hace un tiempo que empezamos a realizar podcast. En ellos varios miembros de la Comunidad KDE de España nos reunimos para hablar un poco de los diversos proyectos.

Hemos hablado de muchos temas como por ejemplo Akademy, KDE Connect, Plasma Mobile, etc.

Podéis seguirnos en  el canal de Youtube de KDE España o en Ivoox, donde estamos subiendo poco a poco los audios emitidos. Esperamos que os gusten.

Asociación LiGNUx: GNU/Linux Distribution Timeline: Junio 2016
Miguel Parada

Miguel Parada
Ubuntizando.com

Telegram desmiente las acusaciones de Gizmodo

telegramwp

Tras leer el reciente articulo publicado en Gizmondo criticando la seguridad de Telegram, me preocupé mucho y decidí investigar sobre el tema y asegurarme de lo que William Turton afirmaba como un riesgo a la seguridad de tus datos fuera cierto. Por supuesto hace tiempo aprendí que en la Internet debes tener varias fuentes para confirmar cierta noticia, nada más fácil que “pagar” para que alguien publique una nota de desprestigio de algo o de alguien. No sería la primera vez que una web de tecnología claramente “se vende” hablando de una cosa o de una persona mal al principio y “mágicamente” muy bien, poco después (¿Verdad Apple Watch?).

Lo primero que encontré es que gran parte del código de Telegram (no todo) es “open source” y puede ser revisado por la comunidad. De hecho hace unos días, Telegram ofreció un premio de “300,000” en Bitcoins a aquella persona que pudiera romper la seguridad de Telegram  y nadie resultó ganador de dicho “concurso”. Muy buen premio para dejarlo pasar. Apostaría que los mejores expertos en seguridad participaron y si nadie lo logró… Por otro lado piensen. Hay que estar muy seguros de lo bueno que es tu software para poner tanto dinero sobre la mesa. 😉

Acto seguido me comuniqué con Telegram. Sí, directamente desde el chat. Después de todo la documentación dice que si quieres hacer una pregunta puedes hacerla. Les mandé el link de la noticia y les pregunté de la opinión respecto al tema. La verdad no esperaba que me respondieran ¿Quien era yo? Un simple usuario, cierto, pero para mi sorpresa respondieron al día siguiente y me ofrecieron su respuesta al articulo. Más abajo la dejo aquí para que alguien más lo lea y saque sus propias conclusiones.

Yo al igual que Telegram pienso que es un “publireportaje” que busca desprestigiarles. Casualmente el mismo articulo recomienda “Signal, iMessage, o WhatsApp” como sustitutos. ¿En serio William? Yo no puedo decirte qué pensar o qué hacer, pero para mi la respuesta está más que clara. Esto es demasiado turbio.

¡Hola! Lo que dice ese artículo no es cierto, probablemente se trate de un artículo comprado con único fin de perjudicar a Telegram.

1. El autor confunde, de forma deliberada, el cifrado y el cifrado end-to-end y dice que algunos datos en Telegram son enviados y almacenados sin cifrar. Esto es falso.

Todos los datos son cifrados. Los chats secretos usan cifrado end-to-end, los chats en la nube usan un cifrado servidor-cliente en tránsito. Los chats en la nube son, por supuesto, cifrados donde se almacenan, también. Las claves de cifrado son repartidas y almacenadas en múltiples centros de datos controlados por diferentes entidades legales y a través de diferentes jurisdicciones. Como resultado, una cooperación intergubernamental poco realista es requerida para forzarnos a entregar algún tipo de dato. (Por ejemplo, diferentes órdenes legales desde diferentes jurisdicciones.) 

2. Un profesor menciona “seguridad por oscuridad” y dice que no es posible analizar el esquema de cifrado de Telegram. Esto también es falso.

Las especificaciones del protocolo de Telegram están disponibles (en detalle: https://core.telegram.org/mtproto ; en resumen: https://core.telegram.org/techfaq).
 Nuestro código de la aplicación, que junto con los documentos permiten evaluar completamente el cifrado end-to-end y su implementación, también es abierto (https://telegram.org/apps#source-code).
 Los investigadores de seguridad tienen todas las herramientas necesarias para evaluar el protocolo de Telegram. 

3. La sección sobre los metadatos y ver a otros usuarios en línea, pues, también es falsa.

A diferencia de WhatsApp, en Telegram puedes controlar quién puede verte en línea o fuera de línea. No importa qué aplicación es utilizada, porque los ajustes son realizados en el servidor.

Mira: https://telegram.org/faq/es#p-puedo-esconder-mi-ltima-conexin y: https://telegram.org/faq/es#p-quin-puede-verme-en-lnea

Si alguien desea que le reenvié el mensaje lo puedo hacer con gusto a través de mi perfil en  Telegram. 😉

screenshot_16-06-29_15-03-36

La entrada Telegram desmiente las acusaciones de Gizmodo aparece primero en Ubuntizando.com.

Miguel Parada

Miguel Parada
Ubuntizando.com

Quake cumple 20 años

QUAKE

Quake fue un juego que lo cambió todo. Recuerdo el primer día que lo jugué. Venía en como una Demo en uno de esos CD que acompañaban a las revistas de la época. Algunos compañeros del colegio me habían hablado de él como “una autentica pasada y no era para menos. Y ya puedes imaginar que, con 16 años que tenía por entonces, aquello tenía que probarlo con mis propios ojos.

En aquella época mi PC era una castaña y debo reconocer que me costó moverlo pero era injugable. Así que recurrí a mi primo al pedirle instalar la Demo en su recién estrenado Pentium 166 MMX de 32MB de memoria RAM. Dos adolescentes ante la luz del monitor, esa ambientación medieval, el espectacular sonido y aquellos gráficos derrochando polígonos y sus sombras dinámicas… Sí, Quake era la puerta a un nuevo mundo.

Parece que fue ayer pero ya pasaron 20 años. John Romero, su co-creador, nos lo recuerda a través de su blog personal. Y es que en Machine Games, estudio creador del nuevo Wolfenstein y herederos de Id Software, han creado un episodio inédito para celebrarlo.

Quake funciona muy bien en Linux e incluso ha salido ganando ya que es posible jugarlo a toda resolución y con efectos añadidos que hace 20 años no podíamos ni soñar. Así que creo que hoy es un buen momento para recordar aquellos años. 😉

Para jugar a Quake en Linux necesitamos los binarios del juego para ello basta con abrir el Centro de Software de Ubuntu y buscamos “Quake” y seleccionamos para su instalación al primer resultado:

quake-centro de software-ubuntu

Una vez instalado ya tenemos el lanzador en nuestro menú de aplicaciones listo para ejecutar nuestro juego pero dará como resultado un error debido a que necesitamos varios archivos .pak del juego original.  El juego podemos comprarlo en Internet sin problemas o descargar la demo oficial así que no es problema. Abrimos una Terminal y seguimos los siguientes pasos:

  • Creamos una carpeta con: sudo mkdir /usr/share/games/quake/id1
  • Accedemos a ella mediante: cd /usr/share/games/quake/id1
  • Procedemos a descargar los archivos que necesita el juego con: sudo wget -c -t0 http://www.mirafiori.com/ftp/pub/gaming/pak0.pak 

Si todo ha ido bien, y luego de unos minutos que termine la descarga,  listo. Ya podemos jugar a Quake 🙂

Nota: No he logrado hacer funcionar el nuevo capitulo. En teoría debemos descargarlo de el siguiente enlace y tras descomprimirlo repetir los pasos anteriores pero creando el directorio “dopa” en lugar de “id1”. Y luego iniciar el juego en el terminal escribiendo quake -game dopa pero no he tenido éxito. :S

La entrada Quake cumple 20 años aparece primero en Ubuntizando.com.

Miércoles 29 de junio de 2016

Baltasar Ortega

Baltasar Ortega
KDE Blog

Cómo cambiar fondo de pantalla de bienvenida en Plasma 5

Hoy quiero explicaros cómo cambiar fondo de pantalla de bienvenida en Plasma 5, esa pantalla que en muchas ocasiones realmente no vemos ya que tenemos un inicio automático pero que si que vemos cuando se bloquea el sistema. Un procedimiento bastante sencillo que se aprende en apenas unos pasos.

Cómo cambiar fondo de pantalla de bienvenida en Plasma 5

Como es habitual para realizar cualquier cosa en Plasma 5 vamos a utilizar un módulo específico de las Preferencias del Sistema de KDE, concretamente uno llamado Comportamiento del Escritorio.

No obstante, primero debemos acceder a las Preferencias del Sistema, y lo haremos iniciando el Lanzador de aplicaciones (del icono que tenemos en la parte inferior izquierda de nuestra pantalla) y buscar dicha aplicación.

Nos aparecerá una ventana como la siguiente y que nos divide en diferentes secciones las opciones de configuración y personalización, y de la que hemos hablado en muchas ocasiones en el blog.

Preferencias del Sistema de Plasma 5

Ahora simplemente debemos pinchar en el icono de “Comportamiento del Escritorio” y acceder a la cuarta sub-sección llamada Bloqueo de Pantalla.

Cómo cambiar fondo de pantalla de bienvenida en Plasma 5

Una vez estemos en dicha pantalla observamos que tenemos varias opciones: tiempo de bloqueo, tiempo para la contraseña, atajo de teclado etc. No obstante nosotros solo vamos a utilizar el último botón de todos: “Fondo personlizado”. Esta opción nos permitirá abrir un cuadro de diálogo para seleccionar el fondo de pantalla deseado y cuya miniatura veremos si ya hemos substituido el que hay por defecto.

Cómo cambiar fondo de pantalla de bienvenida en Plasma 5

Una vez seleccionado el fondo de pantalla deseado simplemente debemos aceptar y aplicar. De este modo tendremos un fondo de bloqueo de Plasma 5 personalizado, como vemos en la imagen inferior, que no es mía pero no se como capturar la pantalla de bloqueo.

Cómo cambiar fondo de pantalla de bienvenida en Plasma 5_02

Como hemo visto algo realmente fácil y sencillo para tener nuestro Plasma 5 lo más personalizado posible.

 

Asociación LiGNUx: Instalemos Arch Linux paso a paso

Martes 28 de junio de 2016

Ramón Ramón Sánchez

Ramón Ramón Sánchez
Software Libre y Comunicación

¿Cómo convertir a un seguidor en votante? 7 secretos para el éxito de un candidato en redes sociales

La elección presidencial de 2018 representará un desafío muy grande para los partidos en México, dado el desprestigio en el que se encuentran los políticos y el descontento y apatía social que la corrupción y la impunidad han provocado. “La nuestra es una sociedad agraviada e incrédula”, resume Víctor Alejandro Espinoza, Investigador del Departamento de Estudios de Administración Pública de... Leer más »

La entrada ¿Cómo convertir a un seguidor en votante? 7 secretos para el éxito de un candidato en redes sociales aparece primero en Software Libre y Comunicación.

Miguel Parada

Miguel Parada
Ubuntizando.com

Disponible Emmabuntüs Debian Edition 1.00

Uno de los grandes problemas del desarrollo de la tecnología no solo reside en la ingente cantidad de recursos necesarios para construir, por ejemplo, el último teléfono de moda. También tenemos el posterior problema de la chatarra electrónica. Cada día se arrojan toneladas de componentes electrónicos a la basura.  Esto genera un grave problema medioambiental pues no se descomponen de forma natural y presentan importantes cantidades de plásticos y metales pesados. El proceso de recuperación es lento y una mejor conciencia del problema por parte de los usuarios y fabricantes ayudaría a mitigar gran parte del problema.

Mientras esto no ocurre, existe otra posibilidad. Podemos rescatar equipos “obsoletos” y darle una nueva vida. Por ejemplo convertirlos en elementos clave para construir una aula informática.  Emmabuntüs es una distribución Linux ligera que está dirigida a comunidades humanitarias, Ongs y etcétera para ser instalada en equipos donados o reacondicionados que destacan por recursos modestos.

Acaba de liberarse Emmabuntüs Debian Édition 1.00  en su versión para procesadores de 32 bits (por ahora) basada en Debian 8.5 y con un entorno de escritorio  XFCE. Podemos consultar las notas del lanzamiento desde el siguiente enlace.

EmmaDE_1.00_news_icons_applications_HandyLinux_ES

 

 

 

La entrada Disponible Emmabuntüs Debian Edition 1.00 aparece primero en Ubuntizando.com.

Baltasar Ortega

Baltasar Ortega
KDE Blog

Eloy Cuadra – Traduciendo KDE (II)

Hoy seguimos con la nueva sección que inauguré en el blog el martes pasado con la entrevista a Javier Viñal. Recordemos que la sección se llamaba Traduciendo KDE y en ella se mostrarán una serie de entrevistas que se han realizado al magnífico equipo de traducción de KDE, gracias al cual podemos disfrutar del trabajo de los programadores KDE en multitud de idiomas. El protagonista de esta segunda entrevista es Eloy Cuadra, miembro del equipo de traducción al español de KDE. Espero que sea de vuestro agrado.

Traduciendo KDE: Eloy Cuadra

Eloy CuadraPara empezar me gustaría que te presentaras tu mismo.

Hola. Soy Eloy Cuadra, natural de Córdoba (España), aunque vivo en Barcelona  desde hace 27 años por motivos laborales. Tengo 51 años y trabajo en Adif como supervisor de circulación (para los profanos en la materia, algo parecido a  controlador aéreo, pero con trenes). Entre mis aficiones están la programación en C++, las ciencias y los idiomas. Me gusta la comida japonesa, la música metal y practico CrossFit.

En lo que se refiere a KDE, soy el actual coordinador del equipo de traducción al español (desde 2010, aunque llevo traduciendo para el equipo desde 2002).

¿Te da mucho trabajo? ¿Hay temporadas de mucha actividad y otras de poca?

Como coordinador, a veces sí y a veces no. Como traductor, suelo dedicar dos o tres horas a la semana. Hace un tiempo había momentos de mucha actividad, justo antes de cada nuevo lanzamiento. Pero en la actualidad, debido a la alta frecuencia de nuevos lanzamientos, la cosa ha cambiado un poco. Ahora resulta más cómodo llevar las traducciones al día.

KDE in progressSiempre es interesante conocer como te iniciaste en este mundo. ¿cómo fue?

Después de usar el antiguo escritorio de KDE durante dos años, me sentía en deuda con la comunidad. Como todavía estaba adaptándome a programar para KDE (recuerdo alguna pequeña colaboración con Kalzium y con Knowit), decidí que era mejor empezar traduciendo. Me uní al equipo de traducción al español en 2002 y empecé traduciendo el paquete kdeutils.

Claro está que este gran TRABAJO suele ser voluntario ¿Cuál es tu motivación y qué te aporta tu labor de traductor?

Me motiva saber que lo que hago le va a servir a otras personas. Por eso, mi labor como traductor me aporta, principalmente, satisfacción. También ha mejorado mi dominio del inglés escrito (o eso espero).

Seamos más específicos y busquemos tu aportación personal. ¿Qué aplicaciones o partes de KDE has traducido?

En la actualidad: digikam y los complementos kipi, extragear-kdevelop, Extragear-sdk, frameworks, kde-workspace, parte del paquete kdeedu, kdegraphics, kdeplasma-addons, kdereview, kdesdk, kdeutils, playground-devtools, playground-sdk y los paquetes kde-runtime, kdelibs y qt de kde4.

También he colaborado con la traducción de otros paquetes en las fechas próximas a un lanzamiento cuando su encargado no podía terminarlas a tiempo.

Además, como coordinador, suelo revisar (y, a veces, corregir) las traducciones que me envían algunos traductores.

Finalmente, procuro que la traducción de los paquetes sin asignar esté más o menos al día.

20 formas de colaborar con KDE

Creo que nadie puede dudar de tu gran trabajo e implicación. De echo es posible que algún lector se motive  y quiera echar una mano ¿cómo puede empezar?

Fácil. Solo tienes que visitar nuestra web. Allí tienes información sobre todo lo que necesitas para unirte a nuestro equipo.

En resumen, se reduce a darte de alta en nuestra lista de correo (para poder estar en contacto) y solicitar la asignación de un paquete libre de playground. En cuanto pueda evaluar la calidad de tus traducciones te pediré que te encargues de un paquete más importante que quede libre.

KDE en las II Jornadas Libres de la UNED

Sé que el equipo de traducción al español lleva mucho traducido ¿Sabes qué está hecho?

Tienes todas las estadísticas a tu disposición en la correspondiente página de la web de la localización de KDE.

Trabajamos en dos ramas: una para kdelibs4 (Plasma 4 y sus aplicaciones) y otra para Frameworks 5 (Plasma 5, Frameworks 5 y sus aplicaciones). Cada una de estas dos ramas posee, a su vez, una rama estable (para la versiones actuales) y otra de desarrollo (para las versiones futuras). Lo que suma un total de cuatro ramas

Por ejemplo, a día de hoy, la traducción al español de la rama estable basada en Frameworks 5 está al 100%, mientras que la rama de lo que serán las próximas versiones basadas en Frameworks 5 está al 99%.

Por tanto ¿qué queda por hacer?

Siempre hay muchas cosas por hacer. Lo más importante es mantener al día las traducciones.

También sería necesario darle un buen empujón a la traducción de la documentación, esa gran olvidada.

Uno de los grandes problemas de todo equipo de traducción es que se heredan traducciones realizadas por otras personas.

En la actualidad, nuestro equipo exige un mínimo de calidad a los  traductores. Pero en los comienzos era más importante que todo estuviera traducido. Y era lógico: todo estaba por traducir y había que hacerlo muy rápidamente. Como resultado, a veces pasamos más tiempo detectando y corrigiendo malas traducciones.

 

Preguntas rápidas

Pasemos ahora a una ronda de cuestiones sencillas pero interesantes. ¿KDE 4 o Plasma 5?

Uso ambos, aunque en breve estaré solo con Plasma 5.

plasma 5.6

Aplicación que más te gusta de KDE

Difícil elección… ¿Vale decir que todas?  Me quedo con Kate, que es la que más uso.

Aplicación que te gustaría tener nativa en KDE

Algo como Evernote. Estoy trabajando en algo parecido

mascot_konqi-dev-kde_620Esto último me ha emocionado, me encantaría tener algo como eso en KDE. Y ahora tu minuto de oro, cuenta lo que quieras para los lectores de KDE Blog.

Puede que traducir un programa o su documentación parezca una tarea difícil,  aunque realmente no lo es. En realidad solo es necesario saber el suficiente inglés y tener un buen dominio de nuestra propia lengua (casi cualquier persona con un mínimo de estudios debería tenerlo). También es necesario estar al día de los cambios que poco a poco va introduciendo la RAE.

Pero también se puede colaborar con nuestro equipo sin saber inglés. Existe una tarea muy sencilla que consiste en capturar imágenes de las ventanas de los programas que traducimos. Esta tarea la puede realizar cualquier persona sin ningún tipo de conocimientos técnicos y lleva mucho tiempo sin asignar.Por eso animo a los lectores de KDE Blog a interesarse por la traducción de KDE.

Estoy seguro que alguno se animará. Gracias Eloy por tu tiempo y por tu trabajo.

Gracias a ti por darnos a conocer y a los lectores de KDE Blog por leernos.

Gorka Urrutia

Gorka Urrutia
Nideaderedes

Programación orientada a objetos en PHP. 3: Encapsulación

Otra entrega más (y ya van tres) del mini curso de programación orientada a objetos en PHP. Esta vez hablo de encapsulación. No te lo pierdas:

 

Programación orientada a objetos en PHP 3: ¿Por qué no hacer todo public? Encapsulación

 

Asociación LiGNUx: Cambiar el prompt de MySQL/MariaDB

Lunes 27 de junio de 2016

Gaspar Fernández

Gaspar Fernández
Poesía Binaria

Cómo hacer login por Facebook en PHP paso a paso

site_access

Hace unos años hice una serie de tutoriales (este, este y este, entre otros) para interactuar con Facebook. Con el tiempo, se han ido quedando antiguos. Han pasado muchas cosas y no he vuelto a revisarlos (además, han dejado de funcionar los antiguos métodos), por lo que he decidido, por fin, renovar toda aquella información.

Aunque esta información cambie con el tiempo, parece que Facebook ha llegado a un punto estable en el que no habrá cambios mayores en su API a no ser que se descubra una vulnerabilidad grave a nivel de diseño, aunque nunca podemos descartarlo.

Antes de nada

No me voy a meter en la forma en la que controláis vuestros sistemas de usuarios. Cada uno tiene implementado el suyo, o utiliza el que viene con su framework preferido, por lo que ese no será el cometido del post. Este post se dedicará únicamente a la creación de una aplicación en Facebook y su utilización para obtener un ID de usuario y un nombre, por lo que tendremos suficiente para hacer login en nuestra aplicación web en nombre del usuario.
Por otra parte, en el código del ejemplo, podemos encontrar clases o funciones temporales que deberán ser sustituidas en un proyecto definitivo ya que están hechas sólo para el ejemplo (clase Storage, por ejemplo).

Creación de la aplicación

Lo primero que tenemos que hacer es acceder a Desarrolladores de Facebook e identificarte. Ahí vamos a encontrar diversas opciones para gestionar nuestras aplicaciones, y lo primero que debemos hacer es crear nuestra aplicación. Para esta guía he puesto capturas de pantalla de las páginas por las que paso que, a junio de 2016 son válidas aunque no descarto que el flujo de trabajo cambie, de todas formas, la esencia será parecida (eso espero).

Para crear la aplicación, para ello, nos dirigimos a Mis Aplicaciones y después Añadir una nueva Aplicación
crea_app_paso1
Luego nos preguntará el tipo de aplicación, o más bien su plataforma, ya que en nuestro caso, quien interactuará con Facebook será una página web, elegiremos www:
Screenshot 22-06-2016-140650
Lo siguiente es darle un nombre a la aplicación. El nombre no debe coincidir con ninguna aplicación nuestra anterior:
Screenshot 22-06-2016-180646
Por último, tenemos que rellenar algunos datos básicos (completar un captcha y ver una pequeña intro que podemos saltar haciendo scroll hacia abajo y Skip):
site_create_data

Tengo la aplicación hecha, ¿ahora qué?

Tras realizar los pasos anteriores llegaremos a un Dashboard de la aplicación:
fb_app_dashboard
Lo importante aquí es el Identificador de la aplicación (o Application ID) y la clave secreta de la aplicación (o Application Secret) y que, será lo que tendremos que introducir en nuestro código.
Como recomendación, esta información se puede almacenar en base de datos si tu web maneja muchos credenciales de aplicaciones de Facebook, o es, por ejemplo un plugin de WordPress que el usuario debe configurar. Aunque, en otras muchas aplicaciones, introduciremos dichos datos en código, aunque para esto, lo ideal es utilizar un archivo de configuración de nuestra aplicación web, o un archivo PHP sólo para estos datos. El objetivo es que podamos tener diferentes datos en desarrollo y en producción y que si subimos el código de desarrollo, estos valores no se vean afectados, incluso el día de mañana, puede que tengamos varios proyectos utilizando el mismo sistema que tengan que ser aplicaciones separadas.

Por lo tanto, yo voy a hacer un pequeño archivo, llamado Config.php, que será una clase de la que puedo leer la configuración de la aplicación. Seguramente en tu aplicación lo hagas de otra forma mucho más completa, aquí sólo está lo justo para que funcione el ejemplo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
namespace App;

class Config
{
  protected static $cfg = array('appId' => "xxxxxxxxxxxxx",
                'appSecret' => "XXXXXXXXXXXXXXXXXXXXXXXXXXXX");

  public static function get($ent)
  {
    if (isset(self::$cfg[$ent]))
      return self::$cfg[$ent];
    return null;
  }

}

Crear el directorio de proyecto e instalar composer

Desde hace un tiempo, el SDK de Facebook utiliza Composer para la gestión de paquetes y dependencias, por lo que debemos instalarlo en nuestro equipo. Podemos seguir las instrucciones para instalarlo, que vienen en la web. De todas formas, para que funcione el ejemplo, lo vamos a instalar en el mismo directorio de nuestro proyecto (no hagáis esto en producción). También cabe decir que por el hecho de utiliza composer, podemos actualizar la biblioteca de Facebook a menudo para estar siempre al día (con cuidado siempre, porque algunas veces cambian algo en el core y puede repercutir en nuestra aplicación).

$ mkdir testfblogin
$ cd testfb
$ wget wget https://getcomposer.org/composer.phar

Instalando el SDK de Facebook

El SDK será un conjunto de bibliotecas que nos ayudarán a interactuar con Facebook de una forma más o menos sencilla. Para instalarlo, utilizando composer, es tan fácil como hacer:

$ composer require facebook/php-sdk-v4

O para este ejemplo, como tenemos composer en el mismo directorio de la aplicación:

$ php composer.phar require facebook/php-sdk-v4

Para aprovechar el autoload de composer en nuestra aplicación, editaremos composer.json y lo dejaremos así:

1
2
3
4
5
6
7
8
9
10
{
    "require": {
        "facebook/php-sdk-v4": "^5.2"
    },
    "autoload": {
    "psr-4": {
        "App\\": "app/"
    }
    }
}

El objetivo es poder trabajar en el directorio app para poder introducir clases para trabajar en nuestro proyecto. Tras eso podemos hacer:

$ composer update

No actualizará ningún paquete (están recién descargados), pero sí que reescribirá los ficheros del autoload para que no tengamos problemas.

Código fuente

Ahora viene un poco de código fuente, debería funcionar tras copiar y pegar (y poner vuestros credenciales de aplicación en Config.php). Eso sí, debemos recordar que esto es sólo un ejemplo. Un sistema real será más complicado, tendrá más opciones y requerimientos propios del proyecto. Esto sería lo mínimo.

Vamos a crear el directorio app dentro del raíz de nuestra aplicación, su contenido será: Config.php (lo pondré de nuevo con alguna línea más que antes) y PoesiaBinaria.php. Lógicamente, en Config.php debéis rellenar vuestros datos de aplicación.

Config.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
namespace App;

class Config
{
  protected static $cfg = array('appId' => "xxxxxxxxxxxxxxx",
                'appSecret' => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                'loginUrl' => "http://midoinio.com/facebook/login.php");

  public static function get($ent)
  {
    if (isset(self::$cfg[$ent]))
      return self::$cfg[$ent];
    return null;
  }
}

PoesiaBinaria.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<?php

namespace App;

class PoesiaBinaria
{
  protected $fb;
  protected $helper;
  protected $loggedUser;
  protected $name;
  protected $id;

  function __construct()
  {
    session_start();
    $this->name = (isset($_SESSION['name']))?$_SESSION['name']:false;
    $this->id = (isset($_SESSION['id']))?$_SESSION['id']:false;
  }

  public function facebookInit()
  {
    $appId = Config::get('appId');
    $appSecret = Config::get('appSecret');
    $this->fb = new \Facebook\Facebook([
                 'app_id' => $appId,
                 'app_secret' => $appSecret,
                 'default_graph_version' => 'v2.6',
                 ]);
    $this->helper = $this->fb->getRedirectLoginHelper();
  }

  public function getLogin()
  {
    $_SESSION['more'] ='';
    $permissions = array();
    $loginUrl = $this->helper->getLoginUrl(Config::get('loginUrl'), $permissions);
    header('Location: '.$loginUrl);
    echo $loginUrl;
    die();
  }

  public function login()
  {
    $this->facebookInit();
    try {
      $at = (isset($_SESSION['accessToken']))?$_SESSION['accessToken']:false;
      if ($at)
    {
      $_SESSION['more'] = "Tengo el access token de antes.";
      $at = unserialize($at);
    }
      if (!$at)
    $at = $this->helper->getAccessToken();
      if (!$at)
    $this->getLogin();

      $this->loggedUser = $this->fb->get('/me', $at);
      $gu = $this->loggedUser->getGraphUser();
      $this->name = $gu->getName();
      $this->id = $gu->getId();
      $_SESSION['name'] = $this->name;
      $_SESSION['id'] = $this->id;
      $_SESSION['accessToken'] = $at;
    } catch(\Facebook\Exceptions\FacebookResponseException $e) {
      $intento = (isset($_SESSION['try']))?$_SESSION['try']:0;
      if ($intento<5)
    {
      $_SESSION['try']=$intento+1;
      $this->getLogin();
    }
      echo 'Graph returned an error: ' . $e->getMessage();
      exit;
    } catch(\Facebook\Exceptions\FacebookSDKException $e) {
      echo 'Facebook SDK returned an error: ' . $e->getMessage();
      exit;
    }
    return true;
  }

  public function getLoggedUser()
  {
    return $this->loggedUser;
  }

  public function getName()
  {
    return $this->name;
  }
 
  public function getId()
  {
    return $this->id;
  }

  public function isLogged()
  {
    return ($this->id!=false);
  }

  public function logout()
  {
    if (isset($_SESSION['name']))
      unset($_SESSION['name']);
    if (isset($_SESSION['id']))
      unset($_SESSION['id']);
  }
};

Ahora, vamos a crear tres ficheros en el directorio raíz: index.php , login.php y logout.php (serán muy sencillos, para hacer llamadas a las funciones de la clase PoesiaBinaria.

index.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
require 'vendor/autoload.php';

$poesia = new \App\PoesiaBinaria();

if ($poesia->isLogged())
  {
    echo "Identificado como usuario: ".$poesia->getName()."<br/>";
    echo "Tu ID de Facebook es: ".$poesia->getId()."<br/>";
    echo '<a href="logout.php">Cerrar sesi&oacute;n</a>';
    if (isset($_SESSION['more']))
      echo "<br/>Mensaje: ".$_SESSION['more'];
  }
else
  {
    echo "Usuario no identificado. Pulsa <a href=\"login.php\">aqu&iacute;</a> para entrar";
  }

login.php:

1
2
3
4
5
6
7
8
9
10
<?php
require 'vendor/autoload.php';

$poesia = new \App\PoesiaBinaria();

if ($poesia->login())
  {
    echo 'Logged in as ' . $poesia->getName(). "(".$poesia->getId().")";
    header('Location: index.php');
  }

logout.php:

1
2
3
4
5
6
7
<?php
require 'vendor/autoload.php';

$poesia = new \App\PoesiaBinaria();

$poesia->logout();
header('Location: index.php');

Proceso de identificación

Una vez subidos los ficheros a nuestro servidor entramos en nuestra página página principal. Se ejecutará nuestro fichero index.php y veremos lo siguiente:
testfb1
Claramente, aún no hemos iniciado el proceso de identificación y no se ha producido aún ninguna comunicación con los servidores de Facebook. Por ahora, todo se ha ejecutado en nuestro servidor, no tenemos ninguna sesión abierta y no nos hemos identificado aún.

Si pulsamos el enlace (que en nuestra web puede tener un icono de la red social, o cualquier cosa parecida), la primera vez que lo hagamos veremos esta pantalla:
testfb2
Aquí es cuando el usuario debe autorizar o no a Facebook para que envíe nuestros datos a la aplicación. Aunque sólo lo veremos la primera vez que realicemos la autentificación.

Tras aceptar, Facebook redirigirá a nuestra loginUrl (Ver archivo Config.php), aportará un código de autorización que utilizaremos para obtener el AccessToken (aunque la misma biblioteca de Facebook se encargará de ello). Nosotros, en login.php haremos la identificación del usuario y estableceremos los valores a las variables de sesión para permanecer identificados en nuestra aplicación. Tras ello, redirigiremos a index.php, en el que veremos lo siguiente:
testfb3
En este punto, podemos utilizar el ID de usuario de Facebook para identificar unívocamente al usuario. Si tenemos un sistema de identificación de usuarios paralelo y similar, por ejemplo, IDs de usuario en nuestro propio sistema (la identificación por Facebook puede ser un método adicional de identificación en nuestra web), podemos almacenar el ID de Facebook junto con los datos de usuario que ya tengamos.

Si pulsamos Cerrar sesión. Eliminaremos las variables de sesión del usuario (en nuestro servidor). Eso no tiene nada que ver con Facebook. Para este ejemplo he dejado el Access Token asociado a la sesión, de esta forma si volvemos a iniciar sesión veremos algo parecido:
testfb4
Aunque con un mensaje menos, como tenemos el Access Token podemos proporcionar una identificación más rápida al usuario ya que realizamos menos intercambio de datos. Es más, no realizamos la identificación directamente, ya que hacemos una petición de datos a Facebook directamente y estábamos autorizados previamente. Eso sí, si ocurre algún error aquí, como por ejemplo el AccessToken caducado o invalidado, sí que repetiríamos todo el proceso.

Podemos guardar los AccessTokens de los usuarios de Facebook para realizar acciones en nombre de los usuarios (por ejemplo enviar publicaciones cuando no están, subir fotos, etc. Todo puede ser utilizado para el bien (hacer la vida de las personas más fáciles) o para el mal… aunque Facebook se toma muy en serio las aplicaciones maliciosas y las persigue.

Cuestión de gustos

Cada vez más aplicaciones web permiten el registro y la identificación por Facebook. De esta forma nos ahorramos verificaciones, petición de datos y damos facilidad al usuario, ya que normalmente todos los usuarios de Facebook estamos identificados en la red social, sólo es pulsar un botón y autorizar la primera vez.

Aunque muchas páginas ofrecen dos opciones: registro e identificación por Facebook, podemos facilitar aún más la vida al usuario si proporcionamos la opción “Entrar por Facebook“. Es decir, la diferencia entre registrarnos e identificarnos es que en el primero escribimos en el registro de nuestro usuario y en el segundo leemos de él. Pero cuando entra en juego la identificación por Facebook el proceso de petición de datos es el mismo. Obtenemos los datos de Facebook de la misma forma, y con el ID de Facebook podemos saber si el usuario es nuevo o viejo. Con todo, podemos saber si es la primera vez que entra y realizar la petición y registro de información de forma totalmente transparente al usuario. Al final:

  • El usuario pulsa Entrar con Facebook
  • El usuario autoriza la aplicación
  • La aplicación comprueba si es la primera vez que entra:
    • Si es la primera vez, pide a Facebook los datos necesarios, crea registros en base de datos y establece la identificación del usuario
    • Si no es la primera vez, establece la identificación del usuario

Más cosas

Pronto, nuevos posts para realizar publicaciones y utilizar Facebook en nuestras propias aplicaciones web.

Foto principal (original): Sarah Stewart

The post Cómo hacer login por Facebook en PHP paso a paso appeared first on Poesía Binaria.

Domingo 26 de junio de 2016

David González

David González
Blog Bitix

El lenguaje de programación, framework y librerías importan

Para programar hay una abundancia tremenda de lenguajes, librerías, frameworks, tecnologías, etc… disponibles para desarrollar un proyecto. Esto es muy bueno ya que podremos elegir la combinación de cualquiera de ellas que más se ajuste a las necesidades del proyecto, las que mejor conozcamos ya o según nuestras preferencias en base a sus características incluyendo su comunidad, documentación, si tiene un desarrollo activo, fecha de la última versión u otros motivos que consideremos. El lado malo de esta abundancia es que requiere analizar seguramente no todas pero al menos las más nombradas, más usadas, con mejor documentación o con un mantenimiento activo. Por la cantidad de opciones dicha tarea de análisis requiere tiempo y esfuerzo que no debe abrumarnos considerando que cualquiera de ellas vale.

Algunas personas piensan que las herramientas no son importantes quizá creen que hay tantas que da igual cualquiera de ellas o que solo importan las personas, «lo que hay entre el teclado y la silla». Entre varias herramientas adecuadas ciertamente en un proyecto no serán lo más importante ni usar alguna en concreto es un fin pero eso no quiere decir que no sean importantes. Son importantes porque afectan de forma notable al desarrollo del proyecto, por poner un ejemplo no es lo mismo un lenguaje o framework que evita errores de compilación en producción, un IDE que los detecta según se escribe el código o que permite hacer refactors con más garantías de no introducir errores que un lenguaje en el que necesitas teses que cubran la totalidad del código simplemente para detectarlos, no es lo mismo el número de lineas necesarias o su verbosidad pero es más importante la legibilidad si va a ser mantenido durante mucho tiempo, no es lo mismo elegir una herramienta ampliamente probada que una implementada por nosotros con el tiempo necesario a dedicar a desarrollarla y que probablemente finalmente sea menos flexible que otra existente, no es lo mismo una base de datos relacional que garantiza la integridad de los datos que una base de datos NoSQL sin validación de esquema. Yendo a un extremo creo que nadie considera siquiera usar ensamblador para hacer una aplicación web o usar Java, hasta el momento, para programar un sistema operativo de alto rendimiento que exprima el máximo potencial del hardware. Pero entre algunas opciones equivalentes cualquiera, con matices, nos servirá, por ejemplo, usar el lenguaje PHP, C# o Java para hacer una aplicación web usando para cada opción los frameworks Symfony, ASP.NET MVC o Apache Tapestry. Hay grados de lo adecuado que es una herramienta para una necesidad.

Por otro lado las herramientas consideradas en el inicio de un proyecto no son inmutables durante toda su existencia y cambian en la medida que las necesidades del proyecto cambian. En una startup al principio se necesitará una combinación de herramientas que permita probar la viabilidad del proyecto y evolucionar rápidamente el producto o servicio. Más tarde según se estabiliza el proyecto y crece surgirán nuevas necesidades como mayor fiabilidad, menos errores y escalabilidad tanto en cantidad de código y número de personas trabajando al mismo tiempo en el mismo código fuente.

También suele haber alguna discusión en si utilizar frameworks o no utilizarlos, usarlos evita tener que desarrollar nosotros mismos mucho código, nos ahorrará tiempo, tendremos mayor flexibilidad y menos errores pero usándolos el proyecto tendrá esa dependencia lo que implica que el código se deberá adaptar a él que aún así igual es algo que queremos para estructurar correctamente el código según el marco de trabajo ofrecido. Por otro lado he presenciado comentarios desfavoreciendo el uso de frameworks, la mayoría de programadores no tienen los conocimientos y tiempo de implementar su propia alternativa con la misma calidad y en la mayoría de los casos basta con reutilizar alguna que cubra la necesidad y más importante esté ampliamente probada.

Para mi lo importante es que para cualquier librería o framework que elijamos tengamos en un futuro la posibilidad de reemplazarlo sin estar encadenados a él y sin tener que reescribir el proyecto entero, esto forma parte de las más básicas buenas prácticas de desarrollo, precisamente las aplicaciones que se desarrollan en capas y los frameworks que separan modelo, de vista, de controlador tratan de minimizar ese impacto.

Cada proyecto es distinto y hay que conocer sus requerimientos para seleccionar las herramientas que contribuyan al éxito o a la menor cantidad de dificultades, si se tratan de un proyecto en la plataforma Java probablemente varias herramientas serán las que indico en el artículo herramientas para un proyecto Java. Si no está clara la plataforma también puedes echarle un vistazo a 10 razones para seguir usando Java y novedades y nuevas características de Java 8.

La tecnologías, lenguajes, librerías, frameworks, … son herramientas a usar para conseguir un fin que es hacer realidad el proyecto, producto o servicio con un componente informático, las herramientas no son un fin en si mismo, no son lo más importante, lo más importante es resolver la necesidad de alguien normalmente con restricciones de tiempo y coste, pero desde luego no son irrelevantes y no da igual usar cualquiera. Son las herramientas equivalentes de un fontanero, pintor, carpintero u otros profesionales que tienen cantidad de ellas para realizar multitud de tareas específicas de forma efectiva y rápida junto con su conocimiento y experiencia. Los lenguajes de programación, frameworks y librerías de no ser importantes no existirían tantas incluso varias con diferentes propiedades para la misma necesidad.

Viernes 24 de junio de 2016

Adrián Arroyo

Migrando

Este es el último artículo que voy a escribir. Pero no te asustes, seguiré escribiendo en mi nuevo y flamante blog.

Este cambio surgió de varios motivos. El primero es el dominio feísimo que tenía. Este año me di cuenta que mucha gente lo estaba usando para enlaces en sus páginas web, pero yo tenía claro que en algún momento lo cambiaría. Decidí no esperar y ya he registrado un dominio definitivo. adrianistan.eu. Lo he comprado en FreeNOM y aunque tuve problemas con el pago (peté el sistema por meter un error de codificación donde no debía) al final el soporte técnico me lo solucionó. Pague 5.60 € por un año del dominio .EU.

Además estaba el diseño del blog. Seamos sinceros. Me gusta tener un blog bonito pero soy un desastre con el diseño. Hice una “mejora” añadiendo Material Design a este blog en Jekyll pero no me terminó de convencer. Había bugs molestos que simplemente no me merecían la pena solucionar. Entonces pensé en algo desde cero usando un tema chulo de Hugo, pero pensé que caería en los mismos errores. Entonces dije WordPress. Si tanta gente lo usa, soporte no me va a faltar y temas y plugins hay para aburrir. Probé WordPress en un sitio de prueba (que para más inri sufrió un ataque DDoS) y me acabé convenciendo. Finalmente instalé Wordpress con Nginx, MariaDB y PHP7 en una Raspberry Pi 2. Como está en mi casa la Raspberry uso NoIP para actualizar la IP de mi casa en el registro DNS. Lleva unos días funcionando, he migrado todo y creo que ya es definitivo.

Los suscriptores por correo habeis sido migrados ya, no hace falta hacer nada. Los que me seguís por un lector de RSS actualizad vuestros feeds. Los que me veis desde algún planeta, pronto se actualizará.

¡Nos vemos en Adrianistán!

David González

David González
Blog Bitix

Combinación de teclas para copiar y pegar en la terminal

Linux
GNU

Usar una combinación de teclas para realizar alguna acción es más rápido que usar el ratón. Si se trata de una acción que realizamos frecuentemente podemos ahorrar bastante tiempo. Yo trabajo bastante con la terminal de GNOME y hasta ahora no sabía cómo copiar y pegar con una combinación de teclas del teclado.

La combinación de teclas estandarizada para copiar y pegar en cualquier aplicación tanto en Linux como en Windows es Ctrl+c para copiar y Ctrl+v para pegar de y al portapapeles. En la terminal (al menos en la de GNOME) cambia ligeramente y hay que usar Ctrl+Shift+c para copiar y Ctrl+Shift+v para pegar el texto en la posición del cursor.

Con el ratón deberemos seleccionar el texto pero con la combinación de teclas nos evitaremos pulsar el botón derecho del ratón, desplazarnos hasta la opción Copiar del menú y finalmente hacer clic en él, para pegar la acción usaremos el mismo menú pero pulsando en la opción Pegar.

Menú para copiar y pegar en la terminal de GNOME

Esto no es algo nada vital pero si es algo que usamos frecuentemente puede hacernos más fácil la tarea y ahorrarnos tiempo al igual que conocer y usar los atajos de teclado básicos de la terminal en GNU/Linux.

Marcelo Fortino

Marcelo Fortino
Fortinux

Ubuntu como entorno de programación y diseño web – PARTE VI

Tutorial Ubuntu como entorno de programación y diseño web - Parte VI Palabras claves: programación web, diseño web, entorno de desarrollo, Ubuntu, front-end developer, full-stack developer, virtualización, LXC.

Miércoles 22 de junio de 2016

Gaspar Fernández

Gaspar Fernández
Poesía Binaria

Redimensionando fotos en PHP evitando que se deformen nuestras imágenes

photo-1464621922360-27f3bf0eca75
En las webs modernas se intenta que el usuario sea capaz de hacer casi de todo. Eso sí, siempre que de cara al servidor sea seguro. Por ejemplo, de nada vale que un usuario pueda generar a través de una web 1000000 de decimales del número PI si mientras tanto ningún usuario más es capaz de hacer nada.
Una de las tareas básicas de una web hoy e día es redimensionar un foto. Es decir, adaptar el tamaño de una foto para adecuarla a nuestras necesidades. Lo primero que tenemos que pensar es que a la hora de transmitir imágenes por la red, tenemos que evitar enviar archivos demasiado grandes. Por ejemplo, si tenemos que mostrar una imagen como máximo a 500×500, debemos evitar enviar la imagen a 4096×4096 ya que no vamos a mostrarla tan grande, vamos a desperdiciar ancho de banda nuestro enviando la foto y tiempo del usuario descargándola.
Todo eso sumado al auge de las webs dinámicas que deben permitir la subida de archivos de imagen al usuario (o al administrador) y de forma sencilla adaptarlas a la web. De forma que se pueda subir una foto directamente de la cámara digital y a la hora de visualizarla en la web quedarnos sólo con el tamaño o los tamaños que necesitemos.

Aunque, como siempre, tenemos varias formas de hacer las cosas, y, sobre todo, hay un factor que debemos tener en cuenta: el aspecto de la foto.

Aspecto de una imagen

El aspecto de una imagen no es más que la relación entre anchura y altura. Vamos, ancho partido por alto. Si os fijáis, es lo mismo que se utiliza en las pantallas. Ahora es común que las pantallas sean 16:9 (panorámicas, que son mucho más anchas que altas), antiguamente los monitores solían ser 4:3 (no eran cuadrados, pero casi). No obstante hay muchas relaciones de aspecto estándar para monitores, proyección, etc.
Cuando hablamos de imágenes, puede haber tantas relaciones de aspecto como imágenes, ya que las fotos podemos recortarlas de mil maneras, y tanto anchura como altura pueden tomar casi cualquier valor y su relación de aspecto se suele expresar como el resultado de la división entre ancho y algo. Si nuestra foto tiene una resolución de 320×240 su relación será 1,33 (¡ anda ! 4/3 da también 1,33 y es que esta imagen se podrá presentar a pantalla completa sin que se observe ninguna deformación), si nuestra foto tiene de dimensiones 600×500 la relación será de 1,2 y si la ponemos a pantalla completa en un monitor 4:3 la veremos deformada.

Dejo aquí la foto original con una resolución de 1280×792 y una relación de aspecto de 1,61:
baterias

Sobre PHP y Frameworks

Si estás trabajando con un framework o una biblioteca especializada en imágenes, seguramente dispongas de funciones o métodos para realizar estas operaciones de forma directa y con algunas opciones más. Pero si te gusta programar PHP a pelo, aquí encontrarás algunas guías que podrán ser útiles para tus proyectos. Aunque podemos utilizar otras bibliotecas para gráficos en PHP, como por ejemplo ImageMagick, estos ejemplos se han hecho utilizando GD.

Las funciones que utilizaré aquí serán sencillas, porque sobre todo el post va encaminado a la matemática de la transformación de las dimensiones y el recorte de la foto.

Redimensionado rápido y directo

Lo que hacemos aquí es cambiar el tamaño de la foto. Nos da igual la relación de aspecto, cogeremos una foto (baterias.jpg) y sean cuales sean sus dimensiones, las cambiaremos.
Para ello utilizaremos imagecopyresampled(), eso sí, si no tenemos cuidado con la resolución que pongamos, la imagen puede quedar deformada.
Si tomamos este código:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

$imagefile = 'baterias.jpg';

/**
 * Opens new image
 *
 * @param $filename
 */

function icreate($filename)
{
  $isize = getimagesize($filename);
  if ($isize['mime']=='image/jpeg')
    return imagecreatefromjpeg($filename);
  elseif ($isize['mime']=='image/png')
    return imagecreatefrompng($filename);
  /* Add as many formats as you can */
}

/**
 * Simple image resample into new image
 *
 * @param $image Image resource
 * @param $width
 * @param $height
 */

function simpleresize($image, $width, $height)
{
  $new = imageCreateTrueColor($width, $height);
  imagecopyresampled($new, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesy($image));
  return $new;
}

$imgh = icreate($imagefile);
$imgr = simpleresize($imgh, 520, 200);

header('Content-type: image/jpeg');
imagejpeg($imgr);

La imagen resultante será:
baterias_500_520_simple
Y, como no hemos respetado la relación de aspecto de la pantalla, la imagen sale deformada, las baterías salen como aplastadas. Esto nos puede servir para imágenes muy pequeñas, o para cuando sepamos (o no nos importe) que la imagen no va a sufrir una deformación.

Una dimensión fija

Si no queremos que la imagen sufra ninguna deformación, lo que podemos hacer es dejar una dimensión fija. Si dejamos el ancho fijo, con la relación de aspecto de la imagen original podemos calcular la nueva altura, y si dejamos la altura fija, podemos calcular la anchura. Siguiendo las siguientes ecuaciones:
ancho_alto
El código sería el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?php

$imagefile = 'baterias.jpg';

/**
 * Opens new image
 *
 * @param $filename
 */

function icreate($filename)
{
  $isize = getimagesize($filename);
  if ($isize['mime']=='image/jpeg')
    return imagecreatefromjpeg($filename);
  elseif ($isize['mime']=='image/png')
    return imagecreatefrompng($filename);
  /* Add as many formats as you can */
}

/**
 * Resize maintaining aspect ratio
 *
 * @param $image
 * @param $width
 */

function resizeAspectW($image, $width)
{
  $aspect = imagesx($image) / imagesy($image);
  $height = $width / $aspect;
  $new = imageCreateTrueColor($width, $height);

  imagecopyresampled($new, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesy($image));
  return $new;
}

/**
 * Resize maintaining aspect ratio
 *
 * @param $image
 * @param $height
 */

function resizeAspectH($image, $height)
{
  $aspect = imagesx($image) / imagesy($image);
  $width = $height * $aspect;
  $new = imageCreateTrueColor($width, $height);

  imagecopyresampled($new, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesy($image));
  return $new;
}

$imgh = icreate($imagefile);
$imgr = resizeAspectH($imgh, 520);

header('Content-type: image/jpeg');
imagejpeg($imgr);

Donde podemos cambiar la llamada a resizeAspectW() por resizeAspectH() dándonos como resultado las siguientes imágenes:

baterias_resized_w
520×321
baterias_resized_h
840×520

Mantener aspecto sin pasarse de dimensiones

El problema con el algoritmo anterior es que las dimensiones pueden crecer mucho. Sobre todo si permitimos que el usuario nos suba fotografías, pueden subir una foto alargada de dimensiones 1×10000 (aspecto 0,0001) si queremos fijar el ancho a 200 la altura saldría a 2000000 lo que es inviable. Por tanto, debemos controlar cuánto crece la imagen. Podemos seguir este código que fijará las dimensiones máximas a las que vamos a tener la imagen resultante. La relación de aspecto se mantendrá y no se superarán las dimensiones fijadas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php

$imagefile = 'baterias.jpg';

/**
 * Opens new image
 *
 * @param $filename
 */

function icreate($filename)
{
  $isize = getimagesize($filename);
  if ($isize['mime']=='image/jpeg')
    return imagecreatefromjpeg($filename);
  elseif ($isize['mime']=='image/png')
    return imagecreatefrompng($filename);
  /* Add as many formats as you can */
}

/**
 * Resize image maintaining aspect ratio, occuping
 * as much as possible with width and height inside
 * params.
 *
 * @param $image
 * @param $width
 * @param $height
 */

function resizeMax($image, $width, $height)
{
  /* Original dimensions */
  $origw = imagesx($image);
  $origh = imagesy($image);

  $ratiow = $width / $origw;
  $ratioh = $height / $origh;
  $ratio = min($ratioh, $ratiow);

  $neww = $origw * $ratio;
  $newh = $origh * $ratio;

  $new = imageCreateTrueColor($neww, $newh);

  imagecopyresampled($new, $image, 0, 0, 0, 0, $neww, $newh, $origw, $origh);
  return $new;
}

$imgh = icreate($imagefile);
$imgr = resizeMax($imgh, 400, 200);

header('Content-type: image/jpeg');
imagejpeg($imgr);

La imagen resultante ahora será (323×200):
baterias_resized_max
Os invito a probar este algoritmo con otras dimensiones de imagen para ver cómo se comporta.

Redimensiona y recorta (resizeCrop)

En el caso anterior, una dimensión sí que quedará fija (se elegirá en función de la relación de aspecto), pero, si queremos que las dos dimensiones queden fijas sin que se pierda la relación de aspecto, lo que debemos hacer es recortar la imagen. De esta forma perderemos información, pero la foto se seguirá viendo bien, aunque deberíamos decidir de dónde perdemos información, ya que si la imagen resultante es más alta que la deseada, debemos perder información vertical y si es más ancha horizontal.
Podemos seguir el siguiente algoritmo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php

$imagefile = 'baterias.jpg';

/**
 * Opens new image
 *
 * @param $filename
 */

function icreate($filename)
{
  $isize = getimagesize($filename);
  if ($isize['mime']=='image/jpeg')
    return imagecreatefromjpeg($filename);
  elseif ($isize['mime']=='image/png')
    return imagecreatefrompng($filename);
  /* Add as many formats as you can */
}

function resizeCrop($image, $width, $height, $displ='center')
{
  /* Original dimensions */
  $origw = imagesx($image);
  $origh = imagesy($image);

  $ratiow = $width / $origw;
  $ratioh = $height / $origh;
  $ratio = max($ratioh, $ratiow); /* This time we want the bigger image */

  $neww = $origw * $ratio;
  $newh = $origh * $ratio;

  $cropw = $neww-$width;
  /* if ($cropw) */
  /*   $cropw/=2; */
  $croph = $newh-$height;
  /* if ($croph) */
  /*   $croph/=2; */

  if ($displ=='center')
    $displ=0.5;
  elseif ($displ=='min')
    $displ=0;
  elseif ($displ=='max')
    $displ=1;

  $new = imageCreateTrueColor($width, $height);

  imagecopyresampled($new, $image, -$cropw*$displ, -$croph*$displ, 0, 0, $width+$cropw, $height+$croph, $origw, $origh);
  return $new;
}

$imgh = icreate($imagefile);
$imgr = resizeCrop($imgh, 520, 500, 0.4);

header('Content-type: image/jpeg');
imagejpeg($imgr);

La imagen resultante será (520×500):
baterias_resized_crop
El cuarto argumento, $displ podrá tener uno de los siguientes valores:

  • ‘min': recortará la imagen arriba o a la izquierda
  • ‘center': se quedará con la parte central de la imagen
  • ‘max': recortará la imagen abajo o a la derecha
  • 0>=x>=1 (cualquier valor entre 0 y 1): desplazará la ventana de recorte hacia la derecha o abajo. Podemos interpretarlo como un porcentaje.

Rotar y recortar

Si queremos aplicar un efecto chulo a nuestras fotos, podemos rotarlas unos grados. El problema es que se crearán unos bordes negros (también podemos hacerlos transparentes), pero nos incomodarán. Así que, vamos a proceder a buscar la región cuadrada más grande de imagen sin bordes y recortar la imagen con esas dimensiones en esa posición (primero redimensiono la imagen para hacerla más cómoda para trabajar):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php

$imagefile = 'baterias.jpg';

/**
 * Opens new image
 *
 * @param $filename
 */

function icreate($filename)
{
  $isize = getimagesize($filename);
  if ($isize['mime']=='image/jpeg')
    return imagecreatefromjpeg($filename);
  elseif ($isize['mime']=='image/png')
    return imagecreatefrompng($filename);
  /* Add as many formats as you can */
}

/**
 * Resize image maintaining aspect ratio, occuping
 * as much as possible with width and height inside
 * params.
 *
 * @param $image
 * @param $width
 * @param $height
 */

function resizeMax($image, $width, $height)
{
  /* Original dimensions */
  $origw = imagesx($image);
  $origh = imagesy($image);

  $ratiow = $width / $origw;
  $ratioh = $height / $origh;
  $ratio = min($ratioh, $ratiow);

  $neww = $origw * $ratio;
  $newh = $origh * $ratio;

  $new = imageCreateTrueColor($neww, $newh);

  imagecopyresampled($new, $image, 0, 0, 0, 0, $neww, $newh, $origw, $origh);
  return $new;
}

function rotateCrop($image, $deg)
{
  $width = imagesx($image);
  $height = imagesy($image);

  $long = max($width, $height);
  $short = min($width, $height);

  $radians = deg2rad($deg);
  $_sin = abs(sin($radians));
  $_cos = abs(cos($radians));

  if ($short <= 2*$_sin*$_cos*$long)
    {
      $x = 0.5*$short;
      if ($width>$height)
    {
      $neww = $x/$_sin;
      $newh = $x/$_cos;
    }
      else
    {
      $neww = $x/$_cos;
      $newh = $x/$sin;
    }
    }
  else
    {
      $_cos2 = $_cos*$_cos - $_sin*$_sin;
      $neww = ($width*$_cos - $height*$_sin)/$_cos2;
      $newh = ($height*$_cos - $width*$_sin)/$_cos2;
    }

  $rot = imagerotate($image, $deg, 0);
  $new = imageCreateTrueColor($neww, $newh);

  imagecopy($new, $rot, 0,0,  imagesx($rot)/2-$neww/2 , imagesy($rot)/2-$newh/2 ,$neww, $newh);
  return $new;

}

$imgh = icreate($imagefile);
$imgr = resizeMax($imgh, 520, 200);
$imgv = rotateCrop($imgr, 30);
header('Content-type: image/jpeg');
imagejpeg($imgv);

El resultado sería algo como esto:
baterias_resized_rotcrop

Foto principal: Tony Webster

The post Redimensionando fotos en PHP evitando que se deformen nuestras imágenes appeared first on Poesía Binaria.

Martes 21 de junio de 2016

Ramón Ramón Sánchez

Ramón Ramón Sánchez
Software Libre y Comunicación

Usabilidad: 10 heurísticas de Nielsen

Hoy en día estamos tan acostumbrados a navegar entre sitios web que muchas veces no nos percatamos de la la facilidad o sencillez con la que utilizamos esa herramienta y es ahí donde entra la usabilidad web. ¿Qué es la Usabilidad Web? Según Wikipedia: La usabilidad es la facilidad con la que las personas utilizan una herramienta u otro objeto... Leer más »

La entrada Usabilidad: 10 heurísticas de Nielsen aparece primero en Software Libre y Comunicación.

Gorka Urrutia

Gorka Urrutia
Nideaderedes

La guía definitiva del código espagueti II: Que tus variables y funciones confundan al enemigo

Porque elegir unos nombres horribles para tus variables y funciones es un arte:

La guía definitiva del código espagueti II: Que tus variables y funciones confundan al enemigo

Gorka Urrutia

Gorka Urrutia
Nideaderedes

[Vídeo] Programación orientada a objetos en PHP 2: Constructores y destructores

No ha habido que esperar tanto como me temía, ya está listo el segundo vídeo de la serie de programación orientada a objetos en PHP:

 

Lunes 20 de junio de 2016

Pedro L. Lucas

Pedro L. Lucas
Cartas de Linux

Mini-manual sobre el formato PDF

Este es un pequeño manual sobre el formato PDF. En la red se pueden encontrar bibliotecas para manejar dicho formato, pero el objetivo un pequeño manual es permitirnos crear nuestros propios archivos PDF usando nuestro editor de textos favorito.

Los ejemplos los podéis descargar desde el siguiente enlace:

https://drive.google.com/folderview?id=0B1x9hVRJS4GmdUZpeVpYR1YzSjQ&usp=sharing

La referencia del formato se puede encontrar en al dirección:

http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf

Desde ahí pos podemos descargar el manual de referencia del lenguaje. Es muy extenso. Pero en este documento vamos a ver las bases más simples y lo usaremos como apoyo.

2 La codificación: ¡No es UTF!

A la hora de escribir desde cero un archivo PDF, es necesario usar la codificación correcta. Para empezar, ¡el UTF no está soportado directamente! El formato PDF soporta varias codificaciones a la hora de escribir sus archivos. Para no complicarnos usaremos la codificación Windows-1252 que los PDF reconocen con el nombre WinAnsiEncoding.

Si usamos Gedit para editar hay que guardar el archivo con “Guardar como” y dará opción a cambiar la codificación de caracteres. Deberemos añadir la Occidental Windows-1252.

También se puede usar el comando “iconv” de Linux.

3 “Hola mundo” en PDF

Una vez puesta la codificación correcta al documento, es hora de escribir nuestro primer archivo “hola_mundo.pdf” (no os preocupéis que después se analizará línea a línea):

%PDF-1.4
1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj
2 0 obj
<< /Type /Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages
/Kids [ 5 0 R
 ]
/Count 1
>>
endobj
4 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
5 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 6 0 R
/Resources <<
/Font << /F1 4 0 R
 >>
>>
>>
endobj
6 0 obj
<< /Length 97 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
BT 283 559 Td /F1 10 Tf (Hola mundo)Tj
ET
endstream
endobj
xref
0 7
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000180 00000 n
0000000287 00000 n
0000000416 00000 n
trailer
<< /Size 7
/Root 1 0 R
>>
startxref
541
%%EOF

En el código del PDF se aprecia que la primera línea es “%PDF-1.4”. Debe ser siempre así e indica que la versión del formato Pdf es la 1.4. Si pusiera “%PDF-1.7”, la versión sería la 1.7.

El archivo está dividido en objetos, veremos unas líneas en las que hay escrito “1 0 obj”, “2 0 obj”, “3 0 obj”,… Estas líneas indican el comienzo de un objeto. El objeto acaba siempre con “endobj”. Los objetos están numerados y la numeración no se debe repetir. No puede haber dos objetos “1 0 obj” en el mismo documento. Después usaremos estos números para llamar a un objeto desde otro.

Los objetos pueden representar páginas, tipos de letra, dibujos, textos,…

Vamos a fijarnos en el objeto “6 0 obj”:

6 0 obj
<< /Length 97 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
BT 283 559 Td /F1 10 Tf (Hola mundo)Tj
ET
endstream
endobj

Este objeto contiene un stream (flujo de datos) y su sintaxis es la siguiente:

n n obj
<< /Length bytes del stream >>
stream
...
endstream
endobj

Es decir, que después de “/Length” hay que poner el número de bytes que ocupa el texto que está entre stream y endstream. En el “6 0 obj” hay 97 bytes entre stream y endstream.

Dentro del objeto “6 0 obj” hay un comando con la forma “(Hola mundo)Tj” es evidente que es el texto que se está dibujando, podríamos modificar el texto a mostrar y tocaría variar el valor de “/Length” según los bytes que ocupe el stream.

Vamos a seguir viendo los objetos de hola_mundo.pdf:

  • 1 0 obj

1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj

Es un catálogo, viene a indicar en que objeto se pueden encontrar las páginas del documento “3 0 obj”. “2 0 obj” hace referencia a un contorno (“/Outline”).

  • 2 0 obj

2 0 obj
<< /Type /Outlines /Count 0 >>
endobj

Por ahora, lo vamos a ignorar. Dentro del catálogo “1 0 obj” es opcional.

  • 3 0 obj

3 0 obj
<< /Type /Pages
/Kids [ 5 0 R
 ]
/Count 1
>>
endobj

Este objeto del tipo “Pages”, páginas, y es un índice de los objetos en los que se representan las páginas del documento. Con “/Kids” se indican los objetos que contienen las páginas. En este caso sólo el objeto “5 0 obj” es una página. “/Count” es el número de páginas del documento. En este caso sólo hay una.

Para poner, por ejemplo, dos páginas una en el objeto “5 0 obj” y otra en el objeto “7 0 obj” se debería cambiar por:

3 0 obj
<< /Type /Pages
/Kids [ 5 0 R
7 0 R
 ]
/Count 2
>>
endobj
  • 4 0 obj

4 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj

Este es un objeto de tipo “/Font” y representa un tipo de letra. En este caso concreto es un tipo de letra “/Helvetica” al que vamos a referirnos en el documento como “/F1” (“/Name /F1”). A partir de ahora, cuando se vaya a escribir un texto y le indiquemos que es el tipo “/F1” se buscará el objeto “4 0 obj” y se pondrá un tipo de letra “/Helvetica”.

Se puede cambiar “/Helvetica” por otros tipos de letra.

Por defecto, los visores de archivos PDF deberían tener los tipos de letra:

/Times-Roman

/Times-Bold

/Times-Italic

/Times-BoldItalic

/Helvetica

/Helvetica-Bold

/Helvetica-Oblique

/Helvetica-BoldOblique

/Courier

/Courier-Bold

/Courier-Oblique

/Courier-BoldOblique

/Symbol

/ZapfDingbats

Por lo que no hará falta incrustarlos en el documento y se podrán hacer documentos más ligeros.

El formato PDF nos permite usar otros tipos de letra que se incrustan en el archivo, pero esto rebasa los límites de este manual.

Hay que definir un objeto de tipo “/Font” por cada tipo de letra que se vaya a usar en el documento.

  • 5 0 obj

5 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 6 0 R
/Resources <<
/Font << /F1 4 0 R
 >>
>>
>>
endobj

Este es un objeto de tipo página (/Page). Tiene una serie de requisitos importantes:

  1. Debe indicar cuál es su objeto padre que le referencia. Es este caso es el objeto “3 0 obj”: /Parent 3 0 R

  2. Tamaño de la página en puntos. Para pasar de mm a puntos usaremos la fórmula x*210.0/74.0. De puntos a mm x*74.0/210.0. En este caso es un A4 con un tamaño de 595×842 puntos: /MediaBox [ 0 0 595 842 ]

  3. Contenidos de la página. En este caso la página va a contener al objeto “6 0 obj” que es el que va a escribir el texto: /Contents 6 0 R

  4. Por último, otros recursos que se van a necesitar para dibujar los elementos de la página como pueden ser los tipos de letra. En este caso se ha indicado que se va a usar el tipo de letra /F1 que se encuentra en el objeto “4 0 obj”:

/Resources <<
/Font << /F1 4 0 R
 >>
>>
>>

Si se necesitasen más tipos de letra en esta página, sólo habría que añadirlos haciendo referencia a su nombre y objeto:

/Resources <<
/Font << /F1 4 0 R
/F2 9 0 R
 >>
>>
  • 6 0 obj

6 0 obj
<< /Length 97 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
BT 283 559 Td /F1 10 Tf (Hola mundo)Tj
ET
endstream
endobj

Este es un objeto stream que ya se ha visto antes. Más adelante veremos los comandos de dibujo. No hace falta decir que es el que dibuja el texto “Hola mundo”.

  • xref

Índice de los objetos. Debe indicar el número de objetos que tiene el documento (se le va a sumar uno, por eso pone xref y a continuación 0 7). Después siempre vamos a poner “0000000000 65535 f”. A continuación se van a poner los bytes que hay desde el comienzo del archivo a la posición del objeto, por ejemplo, hasta el objeto “0 1 obj” hay 9 bytes, hasta el objeto “2 0 obj” hay 74,…

xref
0 7
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000180 00000 n
0000000287 00000 n
0000000416 00000 n
trailer
<< /Size 7
/Root 1 0 R
>>
startxref
541

Después de localizar todos los objetos, viene el “trailer” en el que se indica cuantos objetos hay “/Size 7” (recordad que en este caso son 6 más uno) y se debe indicar cuál es el objeto donde se guarda el catálogo del documento (/Root 1 0 R) que en nuestro caso es el objeto “1 0 obj”.

Las últimas líneas:

startxref
541

Indican cuántos bytes hay desde el comienzo del documento hasta la referencia de objetos xref.

Como os podéis imaginar los lectores del Pdf deberán leer el archivo de atrás a hacia delante para localizar el de xref y tener así el índice con los objetos y su posición en el documento.

  • %%EOF

La última línea indica el final del documento PDF.

Como se puede apreciar el formato Pdf no está diseñado para escribirlo a mano por un humano, pues hay que ir contando bytes. Es ideal para crear desde algún lenguaje de programación.

Truco: Para no tener que andar contando bytes se puede usar el comando “wc -c” desde un terminal lo ejecutamos en Linux y vamos pegando el texto que nos interese. Pulsando Ctrl+D nos indicará el número de bytes que ocupa el texto que hayamos pegado.

Nota: Hay que recordar que los saltos de línea también ocupan bytes.

4 Dibujando

Vamos a fijarnos ahora en el siguiente ejemplo, llamado “dibujos-1.pdf”. Concretamente nos vamos a fijar en el objeto “6 0 obj” que es el que ha incluido la página y está dibujando objetos:

%PDF-1.4
1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj
2 0 obj
<< /Type /Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages
/Kids [ 5 0 R
 ]
/Count 1
>>
endobj
4 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
5 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 6 0 R
/Resources <<
/Font << /F1 4 0 R
/F2 7 0 R
 >>
>>
>>
endobj
6 0 obj
<< /Length 316 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
1 0.5 0 rg 1 0.5 0 RG
 100 742 m 200 642 l S
0.5 0.5 0.5 rg 0.0 0.5 0.0 RG
5 w
20 822 m 40 822 l 30 792 l h S
70 822 m 90 822 l 80 792 l h f
120 822 m 140 822 l 130 792 l  S
BT 100 742 Td /F1 10 Tf (Hola mundo)Tj
0 -10 TD (Adios mundo)Tj
ET
BT 100 642 Td /F2 12 Tf (Hola mundo)Tj
ET
endstream
endobj
7 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F2
/BaseFont /Helvetica-Bold-Oblique
/Encoding /WinAnsiEncoding
>>
endobj
xref
0 8
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000180 00000 n
0000000287 00000 n
0000000426 00000 n
0000000792 00000 n
trailer
<< /Size 8
/Root 1 0 R
>>
startxref
912
%%EOF

Este PDF dibuja la siguiente composición.

Vamos a analizar el objeto “6 0 obj” y concretamente el contenido de su stream que es el que realiza el dibujo:

6 0 obj
<< /Length 316 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
1 0.5 0 rg 1 0.5 0 RG
 100 742 m 200 642 l S
0.5 0.5 0.5 rg 0.0 0.5 0.0 RG
5 w
20 822 m 40 822 l 30 792 l h S
70 822 m 90 822 l 80 792 l h f
120 822 m 140 822 l 130 792 l  S
BT 100 742 Td /F1 10 Tf (Hola mundo)Tj
0 -10 TD (Adios mundo)Tj
ET
BT 100 642 Td /F2 12 Tf (Hola mundo)Tj
ET
endstream
endobj

Dentro del stream nos encontramos los siguientes comandos que pasamos a analizar:

  • 0.0 0.0 0.0 rg 0.0 0.0 0.0 RG

rg sirve para seleccionar el color de relleno de las figuras y RG el color de la línea que dibuja el borde de la figura. Está en formato RGB de forma que el primer número indica el nivel de rojo, el segundo de verde y el tercero de azul. Cada color se expresa con un número de 0 a 1. Así “0 0 0 rg” indica que se va a rellenar de color negro, “1 0 0 rg” de color rojo y “0.3 0.3 0.3 rg” de un color gris oscuro.

  • 1 w

Ancho de línea en puntos. En este se ha seleccionado un ancho de línea de 1 punto.

  • 1 0.5 0 rg 1 0.5 0 RG

Esta línea vuelve a cambiar el color a naranja tanto en el relleno como en las líneas.

  • 100 742 m 200 642 l S

Estos comandos sirven para dibujar una línea recta o un conjunto de líneas rectas. Con “100 742 m” le estamos indicando que la línea va a partir de la posición (100,742), el origen de coordenadas se coloca en la esquina inferior izquierda del papel.

El comando “100 742 m” sólo va a colocar el primer punto de la línea, pero no va a dibujar nada. Con el siguiente comando “200 642 l” le vamos a indicar que dibuje una línea desde la posición anterior a la posición (200,642).

Es decir, el comando “m” coloca el primer punto y el comando “l” dibuja las líneas. Se pueden encadenar varios comandos “l” que irán construyendo una poli-línea. Como se ve en:

20 822 m 40 822 l 30 792 l h S
70 822 m 90 822 l 80 792 l h f
120 822 m 140 822 l 130 792 l  S

Si nos fijamos, vemos que tienen letras al final (h, S, f) cuyo significado es el siguiente:

  • h: Significa que se va a cerrar el línea uniendo el último punto dibujando con el primero.

  • f: Indica que se va a dibujar una figura rellena. Por ejemplo, si dibujamos un triángulo, este triángulo se va rellenar con el color indicado por “rg”.

  • S: Indica que se van a dibujar las líneas que se definen. El color de la línea viene dado por el comando “RG”. Podríamos rellenar una figura pero no dibujar las líneas de los bordes.

  • BT 100 642 Td /F2 12 Tf (Hola mundo)Tj
    ET

Todo los que va desde “BT” hasta “ET” indica que se va a dibujar un texto. En este caso se usará “Td” para colocar la posición del texto. “100 642 Td” coloca el texto en la posición (100,642).

“Tf” se usa para indicar el tipo de letra que previamente se habrá definido en otro objeto. El objeto que define la página tiene que hacer referencia a todos los tipos de letra que se van a usar en la página (ver el objeto “5 0 obj”). Así “/F2 12 Tf” indica que se va a usar el tipo de letra “/F2” con tamaño 12.

“Tj” dibuja el texto. “(Hola mundo)Tj” indica que el texto que se tiene que escribir es “Hola mundo”.

Si sólo se va a dibujar una línea de texto con “Tj” nos vale, pero si se van a dibujar más líneas a continuación, se usa “TD” para indicar la posición relativa respecto de la línea anterior a la que se debe dibujar la siguiente línea. Debemos recordar que si queremos dibujar una línea debajo otra deberemos poner valores negativos. Así el siguiente texto dibujará dos líneas de texto con tipografía “/F1” tamaño 10 en la posición (100,742):

BT 100 742 Td /F1 10 Tf (Hola mundo)Tj
0 -10 TD (Adios mundo)Tj
ET

Como vemos la segunda línea está a una distancia 10 hacia abajo de la primera, “0 -10 TD” indica que el desplazamiento es (0,-10).

Existen una serie de caracteres de escape. Por ejemplo, si queremos escribir un paréntesis veremos que nos dará error pues lo confunde con el paréntesis de cierre del comando “Tj”. Para ello escribiremos:

\( para el símbolo (

\) para el símbolo )

\\ para el símbolo \

En la página 224, apartado 4.4 y del manual:

http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf

Se pueden encontrar otras formas de dibujo como pueden ser las curvas.

5 Transformaciones

Los dibujos que se hagan se pueden transformar haciendo deformaciones, ampliaciones, reducciones,…

Se usarán matrices para realizar dichas transformaciones. Concretamente serán las matrices que tengan la forma:

a b 0
c d 0
e f 1

Claro que representar una matriz de esta forma es muy complejo a la hora de hacerlo con un texto plano, por lo que los elementos de la matriz se escribirán de la forma:

a b c d e f

Así para hacer una traslación se usará la matriz:

1 0 0 1 x y

donde x e y será la distancia que se va a trasladar.

Para una ampliación o reducción se usará:

x 0 0 y 0 0

donde x e y son los factores que se van a ampliar en el eje x y en el eje y.

Para una rotación se usará:

cos(φ) sin(φ) -sin(φ) cos(φ) x y

Donde φ es el ángulo que se va a girar y x e y son las coordenadas el origen.

Antes de hacer una transformación es necesario guardar el estado, se hace con el comando “q”, y al finalizar de realizar la transformación recuperar el estado anterior, se hace con el comando “Q”.

Se usará el comando “cm” para indicar la matriz de transformación que se va a emplear.

Por ejemplo, para dibujar un texto girado 45º:

6 0 obj
<< /Length 165 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
q
 0.7071067811865476 0.7071067811865475 -0.7071067811865475 0.7071067811865476 100 742 cm
BT 0 0 Td /F1 10 Tf (Hola mundo)Tj
ET
Q
endstream
endobj

Vemos que primero se guarde el estado con “q”. Se introduce la matriz de transformación. Hay que fijarse que se ha cambiado el origen de coordenadas, por ello el texto se dibuja en la posición (0,0), y al final aparece en la posición (100,172) que es el origen de coordenadas que se había seleccionado en la matriz. La matriz de transformación se puede apreciar que es:

0.7071067811865476 0.7071067811865475 -0.7071067811865475 0.7071067811865476 100 742 cm

que es justo la que se ha descrito para un giro. En el ejemplo, “dibujos-3.pdf” se puede ver este ejemplo de rotación.

6 He abierto un PDF cualquiera y no entiendo los contenidos de un objeto con un stream

Por lo que se ha contado hasta ahora en el manual, deberíamos poder descargar un PDF cualquiera de Internet, abrirlo con nuestro editor de texto favorito y leerlo. Pero si lo hacemos, nos encontraremos con algo similar a:

4 0 obj <<
/Length 698       
/Filter /FlateDecode
>>
stream
xÚuTÛrÚ0#}ç+ôhÏÄÂ+Ë–Õ§æB&I/¡´ÓÉäÁÁ"x‚Áµ0L~¾+­!&M##‰½œ=»:#°#?ÀÒ˜')S ¸Ò1›•ƒ°s<
 Û###ô‚N¦ƒá9¤,æZ©„Mç#N¢5—R±iÎî¼qmªºXù‘ðZ?à‚ûmå#¸˜Æ8«ò0Äy¯.Fc²4#¸4ä#Èzñ{<º¡íÏÑÍäòú»?½#Œ¦ƒ?{®;#	O

Si nos fijamos, hay una serie de diferencias en este stream. El contenido del stream es ilegible para un humano. Esto es debido a que está comprimido en formato zip para reducir su tamaño. Esto se indica en “/Filter /FlateDecode”.

A parte de “/FlateDecode” el manual de referencia describe otras codificaciones que se pueden usar, como puede ser codificación en hexadecimal,…

7 Dibujo de elipses y circunferencias

En este formato no se pueden dibujar directamente circunferencias o elipses. La siguiente función en Python muestra los cálculos necesarios para dibujarlas:

def elipse(self, x, y, w, h, stroke_ok = False, fill_ok = True):
        y = self.alto - y - h / 2
        x = x - w / 2
        kappa = 0.5522848
        ox = (w / 2) * kappa
        oy = (h / 2) * kappa
        xe = x + w
        ye = y + h
        xm = x + w / 2
        ym = y + h / 2
        text = '{x0} {y0} m {x1} {y1} {x2} {y2} {x3} {y3} c '.format(x0=x, y0=ym, x1=x, y1=ym - oy, x2=xm - ox, y2=y, x3=xm, y3=y)
        text += '{0} {1} {2} {3} {4} {5} c '.format(xm + ox, y, xe, ym - oy, xe, ym)
        text += '{0} {1} {2} {3} {4} {5} c '.format(xe, ym + oy, xm + ox, ye, xm, ye)
        text += '{0} {1} {2} {3} {4} {5} c '.format(xm - ox, ye, x, ym + oy, x, ym)
        if stroke_ok:
            text += b" S"
        if fill_ok:
            text += b" f"
        return text

8 Ejemplo de documento con varias páginas

Este es un ejemplo de varias páginas en el que se tratan de mostrar las diversas formas de dibujar que se pueden encontrar en un PDF (“dibujo-2.pdf”):

%PDF-1.4
1 0 obj
<< /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >>
endobj
2 0 obj
<< /Type /Outlines /Count 0 >>
endobj
3 0 obj
<< /Type /Pages
/Kids [ 5 0 R
7 0 R
9 0 R
 ]
/Count 3
>>
endobj
4 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F1
/BaseFont /Helvetica
/Encoding /WinAnsiEncoding
>>
endobj
5 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 6 0 R
/Resources <<
/Font << /F1 4 0 R
 >>
>>
>>
endobj
6 0 obj
<< /Length 290 >>
stream
0.0 0.0 0.0 rg 0.0 0.0 0.0 RG
1 w
BT 100 742 Td /F1 10 Tf (Página 1:)Tj
0 -10 TD (Dibujo de líneas)Tj
ET
 150 692 m 200 642 l S
0.5 0.5 0.5 rg 0.5 0.5 0.5 RG
5 w
20 622 m 40 622 l 30 592 l h S
70 622 m 90 622 l 80 592 l h f
0 0 0 rg 0 0 0 RG
1 w
100 542 m 200 542 l 200 442 l 100 442 l h S
endstream
endobj
7 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 8 0 R
/Resources <<
/Font << /F1 4 0 R
 >>
>>
>>
endobj
8 0 obj
<< /Length 495 >>
stream
0 0 0 rg 0 0 0 RG
1 w
BT 100 742 Td /F1 10 Tf (Página 2:)Tj
0 -10 TD (Dibujo de curvas)Tj
ET
250.0 542.0 m 250.0 486.77152 272.38576 442.0 300.0 442.0 c 327.61424 442.0 350.0 486.77152 350.0 542.0 c 350.0 597.22848 327.61424 642.0 300.0 642.0 c 272.38576 642.0 250.0 597.22848 250.0 542.0 c  f
350.0 442.0 m 350.0 414.38576 372.38576 392.0 400.0 392.0 c 427.61424 392.0 450.0 414.38576 450.0 442.0 c 450.0 469.61424 427.61424 492.0 400.0 492.0 c 372.38576 492.0 350.0 469.61424 350.0 442.0 c  S
endstream
endobj
9 0 obj
<< /Type /Page
/Parent 3 0 R
/MediaBox [ 0 0 595 842 ]
/Contents 10 0 R
/Resources <<
/Font << /F1 4 0 R
/F2 11 0 R
/F3 12 0 R
/F4 13 0 R
/F5 14 0 R
 >>
>>
>>
endobj
10 0 obj
<< /Length 359 >>
stream
0 0 0 rg 0 0 0 RG
1 w
BT 100 742 Td /F1 10 Tf (Página 3:)Tj
0 -10 TD (Dibujo de Texto)Tj
ET
BT 100 642 Td /F2 12 Tf (Tipo de letra Helvetica-Bold tamaño 12)Tj
ET
BT 100 592 Td /F3 10 Tf (Tipo de letra Courier tamaño 10)Tj
ET
BT 100 542 Td /F4 10 Tf (Tipo de letra Times-Bold tamaño 10)Tj
ET
BT 100 492 Td /F5 10 Tf (Tipo de letra Times-Italic tamaño 10)Tj
ET
endstream
endobj
11 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F2
/BaseFont /Helvetica-Bold
/Encoding /WinAnsiEncoding
>>
endobj
12 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F3
/BaseFont /Courier
/Encoding /WinAnsiEncoding
>>
endobj
13 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F4
/BaseFont /Times-Bold
/Encoding /WinAnsiEncoding
>>
endobj
14 0 obj
<< /Type /Font
/Subtype /Type1
/Name /F5
/BaseFont /Times-Italic
/Encoding /WinAnsiEncoding
>>
endobj
xref
0 15
0000000000 65535 f
0000000009 00000 n
0000000074 00000 n
0000000120 00000 n
0000000192 00000 n
0000000299 00000 n
0000000428 00000 n
0000000768 00000 n
0000000897 00000 n
0000001442 00000 n
0000001616 00000 n
0000002026 00000 n
0000002139 00000 n
0000002245 00000 n
0000002354 00000 n
trailer
<< /Size 15
/Root 1 0 R
>>
startxref
2465
%%EOF

Sábado 18 de junio de 2016

David González

David González
Blog Bitix

Cómo redirigir peticiones de HTTP a HTTPS en Nginx, Apache, Tomcat, Jetty y WildFly

Usar el protocolo seguro HTTPS proporciona confidencialidad en la comunicación entre el navegador del usuario y el servidor, es una forma de mejorar la seguridad y privacidad. Por ello el buscador de Google lo tiene en cuenta como un parámetro que afecta al SEO siendo mejor usar el protocolo seguro. Sin embargo, el usuario puede estar accediendo por el protocolo no seguro a la página web al poner la dirección en la barra de direcciones o hay enlaces hacia nuestro sitio en otros que hacen uso del protocolo HTTP. Si queremos que nuestro sitio sea accedido únicamente usando el protocolo seguro deberemos hacer una redirección en el servidor.

Nginx
Apache HTTPD

Si tenemos una aplicación o una bitácora que hasta el momento era accedido por el protocolo no cifrado HTTP ahora que Google tiene en cuenta para el SEO que usar el protocolo seguro es un parámetro que tiene en cuenta el algoritmo de posicionamiento en el buscador quizá queramos redirigir todo el tráfico de HTTP al protocolo cifrado HTTPS.

Para usar HTTPS deberemos primero configurar el protocolo TLS/SSL en el servidor web o de aplicaciones usando un certificado SSL que podemos obtener ahora con Let’s Encrypt de forma gratuita o generar un certificado nosotros y que sea firmado por una autoridad de confianza. Una vez que el servidor es capaz de servir el tráfico por el protocolo HTTPS estamos en condiciones de realizar la redirección al protocolo cifrado HTTPS en el puerto 443 cuando sea accedido por el protocolo no cifrado HTTP en el puerto 80.

Dependiendo del servidor web o de aplicaciones que usemos la configuración será distinta, incluso lo podemos hacer a nivel de aplicación con la ayuda del framework web si este ofrece algún soporte para ello. A continuación incluiré la configuración necesaria para los servidores web y de aplicaciones más populares como son Nginx, Apache HTTPD, Tomcat, Jetty y WildFly y finalmente el caso haciendo la redirección a nivel de aplicación con el framework Apache Tapestry para desarrollar aplicaciones web con el lenguaje Java.

Nginx

Usando Docker nos resultará más sencillo hacer la prueba que teniendo que instalar el paquete de Nginx en nuestra distribución. Puedes consultar varios artículos sobre Docker que he escrito a modo introducción y para empezar a usarlo.

En la sección del servidor que escucha en el puerto HTTP (80) realizamos la redirección permanente con el código de estado 301 hacia el protocolo HTTPS. En la sección del servidor que escucha en el pueto HTTPS (443) accitva el uso de TLS/SSL usando varias directivas y sirve los documentos de /usr/share/nginx/html en la ruta /.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/nginx.conf">nginx.conf</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/docker-nginx.sh">docker-nginx.sh</pre></a></noscript>
Redirección de HTTP a HTTPS en Nginx

Apache HTTPD

La configuración para Apache HTTPD es similar simplemente cambian las directivas según su propia configuración. Se activan los módulos para usar TLS/SSL y el que permite hacer reescrituras de las URL.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/httpd.conf">httpd.conf</pre></a></noscript>
<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/docker-httpd.sh">docker-httpd.sh</pre></a></noscript>
Redirección de HTTP a HTTPS en Apache HTTPD

Tomcat, Jetty y WildFly

Es muy habitual que los servidores de aplicaciones como Tomcat, Jetty o WildFly sean accedidos no directamente por el navegador del usuario sino a través de un servidor web como Nginx o Apache haciendo de proxy. Cuando hay un servidor web que actúa de proxy para el servidor de aplicaciones es posible decidir que el establecimiento de la conexión cifrada TLS/SSL del protocolo HTTPS se realice en el servidor web y la comunicación cifrada termine al mismo tiempo en él, la comunicación entre el servidor web y el servidor de aplicaciones se realizaría usando el protocolo HTTP. Esto descarga del servidor de aplicaciones la tarea algo costosa del establecimiento de la conexión cifrada y tener que cifrar el tráfico.

Para el caso de Tomcat, Jetty y WildFly habiendo configurado la posibilidad de usar el protocolo seguro la configuración para hacer la redirección es la misma para los tres, habría que añadir al archivo descriptor web.xml de la aplicación el siguiente fragmento XML. Esto hace que el servidor fuerce la conexión segura para los recursos indicados, en este caso todos al usar el patrón /*.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/web.xml">web.xml</pre></a></noscript>

Redirección a nivel de aplicación

Con algún mecanismo propio que empleemos al programar la aplicación (en Java por ejemplo con un filtro) o el framework web que usemos para desarrollar la aplicación web quizá nos ofrezca algún mecanismo para redirigir las peticiones al puerto seguro cuando sea accedida por el puerto inseguro, por ejemplo, para que la redirección la haga la aplicación en vez del servidor con el framework Apache Tapestry basta añadir la siguiente configuración en el módulo de la aplicación.

<noscript><pre><a href="https://gist.githubusercontent.com/picodotdev/505856d7e0a9574541c303d09fd63be1/raw/AppModule.java">AppModule.java</pre></a></noscript>

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./docker-nginx.sh o ./docker-httpd.sh.

Viernes 17 de junio de 2016

Marcelo Fortino

Marcelo Fortino
Fortinux

Ubuntu como entorno de programación y diseño web – PARTE V

Ubuntu como entorno de programación y diseño web - PARTE V programación web, diseño web, entorno de desarrollo, Ubuntu, front-end developer, full-stack developer, Ruby, Rails, Node, Javascript
Gaspar Fernández

Gaspar Fernández
Poesía Binaria

Descubrimos WP-CLI para hacer maravillas y automatizar tu WordPress al máximo

photo-1443916568596-df5a58c445e9
WordPress es el CMS más popular hasta el momento. Solo que orientado al mundo blog o blogosfera, a día de hoy se hacen webs de diversa índole aprovechando sus capacidades de extensión. Aunque a los que llevamos mucho tiempo en la informática, las siglas WP nos recuerdan a WordPerfect1, pero no tiene nada que ver.
Como sabrán muchos lectores de este blog, normalmente prefiero las soluciones de línea de comandos para muchas tareas frente a otras soluciones gráficas más bonitas e intuitivas, ya que éstas últimas suelen ser más lentas, requieren un proceso constante de interacción por mi parte y es muy difícil automatizarlas.

Ahora viene lo bueno, ¿hay alguna forma de utilizar WordPress desde una interfaz de línea de comandos?
¡Por supuesto! Desde finales de 2011 tenemos con nosotros un desarrollo inicialmente hecho por Andreas Creten2 y Cristi Burcä3, aunque ahora su principal mantenedor es Daniel Bachhuber4 (encontramos sus enlaces de GitHub abajo del todo) llamado WP-CLI5.

¿Qué hace WP-CLI?

Básicamente es una interfaz en línea de comandos que nos permite utilizar WordPress sin necesidad de ver una web (aunque sí que necesitaremos acceso SSH al servidor donde tenemos alojado el blog).
Entre otras cosas, nos permite realizar instalaciones de WordPress, instalar plugins, temas, actualizarlos, gestionar comentarios, taxonomías, widgets, posts, páginas, usuarios, base de datos y muchas cosas más, todo desde nuestra línea de comandos. Y, por supuesto, podemos automatizar todas las acciones, lo cual nos permite ahorrar muchísimo tiempo en tareas repetitivas o al menos, si alguna operación va a tardar un rato, no necesitamos estar delante cargando decenas de apartados en el navegador y realizando tareas que requieren nuestra presencia y atención (y, si gestionas muchos blogs te puede venir muy bien).

Requerimientos

Para poder utilizar WP-CLI necesitamos:

  • Acceso SSH a un servidor (para trabajar en remoto), aunque también podemos trabajar en local si queremos. Puede ser Linux, OSX, o cualquier *nix o incluso Windows, aunque en Windows podremos hacer menos cosas.
  • PHP 5.3 o superior (recomiendan 5.3.29, pero funciona con la 5.3.19 sin embargo, a día de hoy, como mínimo una 5.5 la tenemos todos).
  • cURL instalado y su módulo para PHP también.
  • WordPress 3.7 o superior (aunque podremos instalarlo desde WP-CLI, pero no gestionar instancias más antiguas.

Instalación

WP-CLI no es un plugin de WordPress, por lo que no tenemos que instalarlo con el entorno de administración de éste. Es más, WP-CLI es capaz de automatizar tus instalaciones de WordPress. ¿Necesitas hacer varias instalaciones de WP en un servidor? Con esta herramienta puedes hacerlo en cuestión de segundos. WP-CLI será lo primero que instales.

Debemos hacerlo de la siguiente forma:

$ curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
$ sudo mv wp-cli.phar /usr/local/bin/wp
$ sudo chmod +x /usr/local/bin/wp

Con esto, lo tendremos instalado a nivel de sistema. Por lo que, en cualquier lado, podemos ejecutar:

$ wp –info
PHP binary: /usr/local/php54/bin/php-cli
PHP version: 5.4.45
php.ini used: /usr/local/php54/lib/php.ini
WP-CLI root dir: phar://wp-cli.phar
WP-CLI packages dir: /home/poesiab8/.wp-cli/packages/
WP-CLI global config:
WP-CLI project config:
WP-CLI version: 0.23.0

y nos dará información básica sobre el programa. Además, si a menudo trabajas con la línea de comandos, seguro que la tecla Tab la tienes desgastada, porque conseguimos que escriba lo que nos da pereza escribir, además de ayudarnos a recordar mucha información. Esto se llama bash completion, y muchísimos vienen acompañados de un pequeño script que nos ayuda con esto. WP-CLI no va a ser menos. Podemos descargarlo e instalarlo:

wget https://github.com/wp-cli/wp-cli/raw/master/utils/wp-completion.bash
sudo mkdir -p /usr/local/share/bash-completion/completions
sudo mv wp-completion.bash /usr/local/share/bash-completion/completions

Ahora en nuestro $HOME, añadir al archivo .bashrc las siguientes líneas al final:

1
2
3
4
if [ -f "/usr/local/share/bash-completion/completions/wp-completion.bash" ];
then
   source /usr/local/share/bash-completion/completions/wp-completion.bash;
fi

Así, nada más entrando en el sistema podremos disfrutar de esta ayuda. Si no queremos salir y volver a entrar, podemos hacer:

$ source /usr/local/share/bash-completion/completions/wp-completion.bash

Recapitulando

También podemos crear un pequeño script que lo haga todo por nosotros, muy útil si tenemos que hacer varias instalaciones de WP-CLI (el script necesita sudo, y preguntará la contraseña, pero no es difícil de adaptar):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#/bin/bash

OLDPWD="$(pwd)"
cd /tmp/

# Descarga e instala WP-CLI
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp
sudo chmod +x /usr/local/bin/wp

# Descarga e instala WP-CLI completion
wget https://github.com/wp-cli/wp-cli/raw/master/utils/wp-completion.bash
sudo mkdir -p /usr/local/share/bash-completion/completions
sudo mv wp-completion.bash /usr/local/share/bash-completion/completions

# Instala WP-CLI completion en el usuario actual
cp $HOME/.bashrc $HOME/.bashrc_old
echo "if [ -f \"/usr/local/share/bash-completion/completions/wp-completion.bash\" ]
then
    source /usr/local/share/bash-completion/completions/wp-completion.bash;
fi"
>> $HOME/.bashrc
source /usr/local/share/bash-completion/completions/wp-completion.bash

cd "$OLDPW"

También podemos instalarlo en Windows, o utilizar Composer o Brew, tenemos mucha más información en la web oficial.6.

Actualización

WP-CLI soporta auto-actualización (como composer), es decir, ejecutando:

$ wp cli update

Automáticamente se descargará la última versión y se sobreescribirá el archivo actual (debemos tener permisos para ello, por ejemplo si está instalado con privilegios de root, debemos ser root, o hacer sudo si está disponible).

Antes de empezar

WP-CLI puede administrar múltiples instancias de WordPress en un mismo servidor, tanto si tienes una instalación para cada blog WordPress como si dispones de configuración multisitio7.
Es recomendable, antes de utilizar WP-CLI acceder al directorio del servidor donde tenemos la instalación de WordPress (a no ser que lo estemos instalando), de la siguiente forma:

$ cd www/mi_blog/www/
$ wp core version

Aunque, también podemos hacer lo siguiente (aunque puede ser algo incómodo):

$ wp core version –path=www/mi_blog/www

Tareas básicas

Ahora viene lo interesante, todo lo que podemos hacer con WP-CLI, al menos algunas tareas comunes como las siguientes:

Instalación de WordPress

Para hacer la instalación, debemos dar varios pasos previos:

  • Descarga de archivos: seguro que alguna vez te has descargado WordPress, lo has descomprimido en tu ordenador y lo has subido al servidor por FTP. Al tratarse de muchos archivos, este método es lento, necesita mucha interacción humana, además, la conexión a Internet de un ordenador personal suele ser mucho más lenta que la de un servidor. Por otro lado, el servidor puede hacer muchas cosas, si has usado SSH antes, sabrás lo que quiero decir. WP-CLI nos permite descargar y descomprimir WordPress con sólo un comando.

    $ wp download –path=directorio_local –locale=idioma

  • Configuración de WordPress: el primer paso, tras la instalación es decir el host, nombre de usuario, clave y demás información relativa a la base de datos. Pero esto lo podemos automatizar, quitar el mensaje de bienvenida y ahorrar un precioso tiempo:

    $ wp core config –dbname=”BASEDEDATOS” –dbuser=”USUARIODB” –dbpass=”PASSDB” –dbhost=”HOSTDB” –dbprefix=”PREFIJODB” –locale=”idioma”

  • Instalación de WordPress: tras enviar la información de base de datos, nos pedirá información sobre el blog; darle un nombre, un usuario administrador y una contraseña. Esto lo podemos hacer con:

    $ wp core install –url=”DIRECCION” –title=”TITULO DEL BLOG” –admin_user=”USUARIO_ADMINISTRADOR” –admin_password=”PASSWORD” –admin_email=”MAIL ADMINISTRADOR”

  • Un ejemplo real

    Queremos instalar un WordPress en español en www.midominio.com/blog; la base de datos estará en localhost (en el mismo servidor web), el usuario será dbuser, la clave dbpassword, la base de datos, blogs y el prefijo “wp_”. El usuario administrador de WordPress será blogadmin y la clave “passwordcomplicado”. El título del blog será “Un blog sobre WP-CLI”. Podremos hacerlo ejecutando tres comandos:

    $ wp download –path=www/blog –locale=”es_ES”
    $ cd www/blog
    $ wp core config –dbname=”blogs” –dbuser=”dbuser” –dbpass=”dbpassword” –dbhost=”localhost” –dbprefix=”wp_” –locale=”es_ES”
    $ wp core install –url=”http://midominio.com/blog” –title=”Un blog sobre WP-CLI” –admin_user=”blogadmin” –admin_password=”passwordcomplicado” –admin_email=”info@midominio.com”

    O si queremos algo más general… incluso para que nos dé un password generado, tal y como hace un WordPress moderno:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    DB_HOST="localhost"
    DB_USER="dbuser"
    DB_PASSWORD="dbpassword"
    DB_NAME="blogs"
    DB_PREFIX="wp_"

    WP_TITLE="Un blog sobre WP-CLI"
    WP_LOCALE="es_ES"
    WP_URL="http://midominio.com/blog"

    ADMIN_PASSWORD=$(pwgen -sy 12 1)
    ADMIN_USER="blogadmin"
    ADMIN_MAIL="info@midominio.com"

    wp download --path=www/blog --locale="$WP_LOCALE"
    cd www/blog
    wp core config --dbname="$DB_NAME" --dbuser="$DB_USER" --dbpass="$DB_PASSWORD" --dbhost="$DB_HOST" --dbprefix="$DB_PREFIX" --locale="$WP_LOCALE"
    wp core install --url="$WP_URL" --title="$WP_TITLE" --admin_user="$ADMIN_USER" --admin_password="$ADMIN_PASSWORD" --admin_email="$ADMIN_MAIL"
    echo "El password es: "$ADMIN_PASSWORD

    Esto nos puede permitir automatizar al máximo la creación de blogs. Por ejemplo si tenemos varias webs alojadas en el mismo servicio de hospedaje, o un VPS. Esto nos puede hacer ahorrar muchísimo tiempo.
    ¿Parece poco ahorro? Bueno, como veremos más adelante, podremos instalar plugins desde aquí, podemos crear un pequeño script que automatice la instalación de WordPress, plugins y algo de configuración básica.

    Copia de seguridad

    Podemos importar y exportar la base de datos de forma muy rápida con las siguientes órdenes:

    $ wp db export backup.sql

    Y luego

    $ wp db import backup.sql

    Lo que nos puede ayudar bastante para las copias de seguridad. No está de más hacer una copia de los archivos, si el directorio de WordPress está en /home/usuario/www/blog/ podemos ir a /home/usuario y hacer lo siguiente:

    $ tar cvjpf blog_backup.tar.bz2 www/blog

    para realizar la copia y,

    $ tar xvjpf blog_backup.tar.bz2

    para restaurarla.

    De todas formas, existen plugins que pueden interactuar con WP-CLI para realizar una copia completa de seguridad8

    Actualizar versión

    Si hacemos:

    $ wp core version
    4.5.0

    Nos mostrará la versión que tenemos instalada actualmente (El post está publicado el 17 de junio de 2016). Nota: no me gusta hacer actualizaciones del core o de plugins/temas/etc sin haber hecho un backup completo primero. En el pasado, hacerlo así me ha salvado la vida varias veces.

    A partir de aquí podemos hacer una actualización:

    $ wp core update

    Automáticamente se actualizará y se instalará la actualización. No está de más hacer justo después:

    $ wp core update-db

    Ahora probamos nuestro blog, y navegamos un poco para ver que todo está bien.

    Ejecutar SQL directamente

    Esto me encanta. Normalmente puedo acceder a la base de datos ejecutando el comando mysql, con usuario y password de un usuario con privilegios (al tener varios blogs, tengo varios usuarios de base de datos con passwords generados, no me los sé todos y me da mucha pereza mirarlos).
    De esta forma, al ejecutar WP-CLI sobre un blog determinado, se ejecutará la consulta sólo sobre el usuario de dicho blog, por lo que la seguridad no será ya un problema.
    Podemos hacer:

    $ wp db query “SHOW TABLES;”

    o si tenemos la consulta SQL en un archivo:

    $ wp db query < consultas.sql

    ¿Quieres saber qué puedes hacer desde aquí? Visita este post para coger ideas.

    Configurar (de todo)

    Una de las tareas más arduas cuando instalas WordPress es configurarlo, recorrer todas las opciones y pasar por varias pantallas hasta finalizar todos los parámetros de configuración disponibles. Algunos los definimos, otros los revisamos, pero entre opciones del tema, plugins, generales, etc serán varias pantallas y si tenemos que configurar varios blogs, podemos perder muchísimo tiempo en estas tareas.

    Para ello tenemos:

    wp option

    Que nos permitirá consultar y definir valores de configuración de WordPress. Para empezar, podemos listar los elementos que nos deja configurar:

    $ wp option list

    Con esto veremos un listado de todas las opciones presentes, algo parecido a esto:
    Screenshot 14-06-2016-230644

    También tenemos las órdenes:

    $ wp option get [opcion]

    Pero claro, en este gestor de contenidos, si hemos revisado alguna vez las opciones del plugin (o hemos hecho un traslado de dominio a través de una copia de seguridad de la base de datos) veremos que muchas configuraciones vienen serializadas, es decir, tienen la siguiente forma:

    |widget_categories|
    a:2:{i:2;a:4:{s:5:”title”;s:0:””;s:5:”count”;i:0;s:12:”hierarchical”;i:0;s:8:”dropdown”;i:0;}s:12:”_multiwidget”;i:1;}

    Personalmente no me gusta, pero en WordPress no tenemos muchas más formas de categorizar una configuración y, desde el punto de vista de PHP es muy fácil y rápido serializar un array para escribir dicha configuración en base de datos. Aunque wp option get nos permite visualizar la variable de configuración con naturalidad, así:

    array (
    2 =>
    array (
    ‘title’ => ”,
    ‘count’ => 0,
    ‘hierarchical’ => 0,
    ‘dropdown’ => 0,
    ),
    ‘_multiwidget’ => 1,
    )

    De igual forma, podemos definir valores a las opciones de WordPress, como siempre, con vistas a configurar blogs de forma automática, utilizando:

    $ wp option set [opción] [valor]

    Tal y como sucedía con el ejemplo anterior, los nombres de las opciones, los podemos conseguir cuando obtenemos la lista, una de las cosas que podemos definir es:

    $ wp option set rss_use_excerpt 1

    El problema, como antes, surge cuando queremos cambiar uno de los valores que vienen en un array serializado, lo cual podríamos hacerlo de varias formas, entre ellas:

    • Podemos obtener el dato serializado en json:

      $ wp option get widget_categories –format=json

      luego editar el dato dentro del json resultante, por ejemplo el título, y volver a cargar en JSON las opciones:

      $ wp option set widget_categories –format=json ‘{“2″:{“title”:”Categor”,”Counts”:0,”hierarchical”:0,”dropdown”:0},”_multiwidget”:1}’

      aunque de esta forma necesitaríamos algo de interacción, o crear una expresión regular.

    • No obstante podemos utilizar PHP para convertir el JSON en un array, editar el contenido desde el array y volverlo a pasar a JSON:

      wp option set widget_categories “$(echo “{2}->title=’Categorias'; echo json_encode(\$original);” | php -n)”

      Estamos haciéndolo todo del tirón desde un script de bash. Veámoslo detenidamente:

      • wp option set widget_categories “VALOR” : definirá el valor en las opciones de WordPress. Aunque para definir el valor, vamos a utilizar una secuencia de comandos.
      • $(echo “<?php ÓRDENES PHP;” | php)” : Interpretará las órdenes en PHP y las pasará como argumento (al comando anterior)
      • $(wp option get widget_categories –format=json) : Obtendrá el valor en JSON de la opción widget_categories y lo pasará como argumento (que lo hemos metido dentro del PHP que estamos interpretando).
      • Como las variables PHP y las variables de BASH empiezan por $ para definir una variable en PHP tenemos que escapar el símbolo de $ poniendo una \ delante.

    Información sobre los posts

    Podemos, también obtener información sobre los posts publicados, como listarlos:

    $ wp post list

    donde obtendremos IDs, títulos, slugs, fechas y estados (si está publicado, borrador, programado…), aunque si leemos la documentación veremos opciones para filtrar la búsqueda por diferentes criterios; o bien, obtener información completa de un post concreto como:

    $ wp post get 1

    donde 1, en este caso es el ID del post que queremos visualizar, devolviéndonos algo como esto:

    +-----------------------+-----------------------------------------------------+
    | Field                 | Value                                               |
    +-----------------------+-----------------------------------------------------+
    | ID                    | 1                                                   |
    | post_author           | 1                                                   |
    | post_date             | 2016-06-12 13:37:08                                 |
    | post_date_gmt         | 2016-06-12 13:37:08                                 |
    | post_content          | Bienvenido a WordPress. Esta es tu primera entrada. |
    |                       |  Edítala o bórrala, ¡y comienza a escribir!         |
    | post_title            | ¡Hola mundo!                                        |
    | post_excerpt          |                                                     |
    | post_status           | publish                                             |
    | comment_status        | open                                                |
    | ping_status           | open                                                |
    | post_password         |                                                     |
    | post_name             | hola-mundo                                          |
    | to_ping               |                                                     |
    | pinged                |                                                     |
    | post_modified         | 2016-06-12 13:37:08                                 |
    | post_modified_gmt     | 2016-06-12 13:37:08                                 |
    | post_content_filtered |                                                     |
    | post_parent           | 0                                                   |
    | guid                  | http://mi-blog.com/?p=1                             |
    | menu_order            | 0                                                   |
    | post_type             | post                                                |
    | post_mime_type        |                                                     |
    | comment_count         | 1                                                   |
    +-----------------------+-----------------------------------------------------+
    

    Esto puede ser útil, incluso si ponemos –format=json en la llamada anterior para obtener toda la información del post y pasarla a otro programa o a un script y aplicarle un tratamiento, podríamos hacer búsquedas por contenido.

    Borrar posts automáticamente

    Igual que podemos crear, podemos destruir. Puede que alguna vez hayamos creado un post con fecha de caducidad, cuya información no es válida o no tiene sentido pasada una fecha, por ejemplo, si hacemos una campaña de publicidad de un producto o servicio. Podemos hacer que cuando llegue la fecha límite, dicha publicidad desaparezca:

    $ wp post delete ID

    que manda el post a la papelera la primera vez que se ejecuta (la segunda vez borra definitivamente el post) o,

    $ wp post delete ID –force

    que lo borra directamente.

    Aunque, si hemos generado varios posts de prueba, podemos eliminarlos todos de la siguiente manera:

    $ wp post delete {1..100}

    que borraría todos los posts con IDs comprendidas entre 1 y 100.

    Un escritor automático

    Para terminar con el listado de opciones de WP-CLI en este post (porque este programa da muchísimo más de sí), vamos a hablar de la escritura de posts de forma automática. En primer lugar, podemos generar una serie de posts idénticos, lo que nos puede servir para hacer pruebas con temas o plugins de la siguiente forma:

    $ curl http://loripsum.net/api/5 | wp post generate –post_content –count=10

    Así, primero nos bajamos un texto de lorem ipsum y luego lo pasamos al generador de posts, que creará 10 posts con ese contenido. Podríamos crear también páginas si añadimos (–post_type=page) o modificar la fecha con (–post-date “yyyy-mm-dd”).

    Aunque lo que de verdad se lleva la palma es la capacidad de enviar posts. Es decir, podríamos hacer un programa o script que creara un post o página automáticamente con contenidos de diferentes fuentes en diversas condiciones. Podemos poner como ejemplo un post que se envíe automáticamente cuando da lluvia a través de una web meteorológica o si queremos dejar volar nuestra imaginación, cuando nuestro proyecto con Arduino detecta lluvias; o incluso un post que se despida del mundo cuando estemos muertos si, por ejemplo, llevamos mucho tiempo sin entrar en el servidor o hacer una tarea rutinaria, sólo por poner algunos ejemplos.
    A la hora de enviar el post debemos hacer lo siguiente:

    $ wp post create [fichero_de_contenidos] –post-type=post –post-title=”Título de mi post” –post-category=12,32,54

    De esta forma leeremos un fichero de texto con el contenido del post (que también podemos generarlo con un script o descargarlo…), en el tipo podríamos especificar post o página, el título lo podemos personalizar también así como la categoría (que tiene que ir por número).

    También podemos programar un post si especificamos –post-status=future –post-date=”yyyy-mm-dd HH:MM:SS”.

    Y mucho más…

    Podría rellenar varios posts con las capacidades de WP-CLI, pero debemos dejar algo a la imaginación y la investigación. ¿Qué más cosas podemos hacer?

    • Administrar usuarios
    • Administrar los permisos de los diferentes roles de usuarios (wp cap)
    • Administrar cachés (wp cache)
    • Administrar tareas programadas o cron jobs (wp cron)
    • Administrar menús
    • Administrar plugins del propio WP-CLI que nos permitirán funciones personalizadas (wp package)
    • Muchísimo más

    WP-CLI en Siteground

    Siteground España es un proveedor especializado en servicios de hosting WordPress profesionales con servidores robustos y que facilita enormemente la labor de administrar un blog con WordPress manteniendo constantemente todos los sistemas al día.

    Y, por supuesto, no podían dejar a los amantes de la consola de lado, proporcionando un acceso por SSH a los servidores, y por supuesto, disponemos de una instalación de WP-CLI siempre actualizada.

    Para conectar por SSH a nuestro sitio de SiteGround, primero, debemos acceder a cPanel y buscar en las opciones Acceso SSH Shell
    Screenshot 16-06-2016-000641
    Luego, en la siguiente pantalla, debemos configurar nuestra clave RSA, para ello, aunque SiteGround nos permite generar un par de claves desde el entorno web y descargarnos nuestra clave privada (que luego tendremos que copiar en nuestro equipo), yo prefiero ejecutar lo siguiente en mi terminal:

    $ ssh-keygen -b 4096

    Luego puedo guardar mi clave en mi ordenador, y subir la clave pública (copiar y pegar) donde pone Upload SSH key:
    Screenshot 16-06-2016-000649

    Luego, una vez hecho esto, basta con acceder al SSH de nuestro servidor en SiteGround desde un terminal:

    $ ssh -p 18765 [usuario]@[dominio.com]

    Donde el usuario es el mismo que utilizas para entrar en el panel de control de SiteGround y el dominio es tu dominio principal del hosting.

    Ahora, sólo puedo decir una cosa… ¡ a disfrutar !

    Referencias

    Al ser un post patrocinado, y como hice otras veces, los enlaces externos que incluyo a lo largo del post, los resumo aquí, y que los enlaces de la marca sean los primeros.

  1. Wordperfect
  2. Andreas Creten
  3. Cristi Burcă
  4. Daniel Bachhuber
  5. WP-CLI oficial
  6. Installing WP-CLI
  7. Cómo activar MultiSitio en WordPress
  8. Backup WordPress Plugin
  9. 21 Consultas SQL para administrar fácilmente nuestro WordPress

Foto: Austin Schmid

The post Descubrimos WP-CLI para hacer maravillas y automatizar tu WordPress al máximo appeared first on Poesía Binaria.

Jueves 16 de junio de 2016

BlogDRAKE: Pequeñas novedades
Ramón Ramón Sánchez

Ramón Ramón Sánchez
Software Libre y Comunicación

Analista Digital: Herramientas libres

El día a día de un analista digital pasa por ser capaz de digerir toda la información que recibe a través de Internet y que debe ser segmentada y de fácil manipulación. Para ello disponemos de muchas herramientas que nos facilitan algunas de las tareas que debemos realizar y que os quiero presentar a continuación, el único requisito de esta lista... Leer más »

La entrada Analista Digital: Herramientas libres aparece primero en Software Libre y Comunicación.

Miércoles 15 de junio de 2016

José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

StartEncrypt, la respuesta de StartSSL a Let’s Encrypt

seguridad StartSSL, pionera en esto de dar certificados gratutitos, ha lanzado una agresiva campaña de respuesta a Let’s Encrypt ofreciéndonos su propio servicio para automatizar la instalación, gestión y renovación de certificados: StartEncrypt. Si alguien lo ha probado ya que avise y, si no, tendremos que hacerlo por aquí en breve. Que remedio 😉

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: StartEncrypt, la respuesta de StartSSL a Let’s Encrypt || Hospedado en un Cloud VPS de Gigas.

Viernes 10 de junio de 2016

Marcelo Fortino

Marcelo Fortino
Fortinux

Ubuntu como entorno de programación y diseño web – PARTE IV

Tutorial Ubuntu como entorno de programación y diseño web Palabras claves: programación web, diseño web, entorno de desarrollo, Ubuntu, front-end developer, full-stack developer, application server, Java, PHP, Python, C, C++.

Jueves 09 de junio de 2016

Viajes y otras cosas

Durante las próximas semanas tendré una rápida sucesión de viajes y trabajo a alta densidad (de junio a agosto, justo cuando la mayor parte de la gente tiende a tomarse vacaciones yo estoy en mi pico laboral) por lo que las entradas del blog van a ser escasas. De hecho en las próximas semanas se […]

Lunes 06 de junio de 2016

Probando LibreOffice Writer 5.2 beta 1

Para el usuario casual y a primer golpe de vista LibO 5.2 beta 1 podría parecer no muy diferente de 5.1.x, pero como sabrá el lector de este blog yo no soy precisamente un usuario casual de Writer por lo que mi impresión al abrir por primera vez esta versión de desarrollo fue de agradable […]

Domingo 05 de junio de 2016

Tor Browser 6 tendrá a DuckDuckGo como buscador

Recientemente se ha lanzado la nueva versión de uno de los navegadores más utilizados desde ordenadores con Linux, se trata de Tor Browser 6, un navegador web que ha elegido como buscador predeterminado a DuckDuckGo, un proyecto independiente que ha estado creciendo bastante en este último tiempo. DuckDuckGo es un buscador web de contenidos bastante particular puesto que el mismo permite que los

Sábado 04 de junio de 2016

Adrián Arroyo

Programando para Haiku - File panel - Parte II

Continuamos los tutoriales de programación en Haiku. Hoy veremos como usar el File Panel. ¿Qué es el File Panel? El File Panel es el diálogo que nos aparece cuando queremos abrir o guardar un archivo o carpeta. En todos los sistemas operativos gráficos es similar.

File Panel de Windows

BFilePanel

La clase básica es BFilePanel. Esta clase se encarga de mostrar esa ventanita que nos deja elegir el archivo o carpeta para abrir o para guardar. Lo primero que tenemos que saber si queremos hacer un File Panel es si va a ser para abrir un archivo existente o para guardar un nuevo archivo. Así, distinguimos entre B_OPEN_PANEL y B_SAVE_PANEL. Si estamos dentro de un B_OPEN_PANEL además indicaremos si aceptamos archivos, carpetas, enlaces simbólicos o alguna combinación de estas cosas. Por último, ¿cómo recibimos la información del panel? Pues usando BMessage, como es habitual en Haiku/BeOS. Pero hay que indicar quién va procesar el mensaje, el conocido como BMessenger. Veamos código:

const uint32 OPEN_FILE = 42;
BFilePanel* filepanel = new BFilePanel(B_OPEN_PANEL,new BMessenger(this),NULL,B_FILE_NODE,new BMessage(OPEN_FILE));
filepanel->Show();

En este código creamos un file panel para abrir un archivo. El BMessenger encargado de procesarlo será el del mismo contexto en el que se ejecute este código. Hay que tener en cuenta que tanto BApplication como BWindow heredan de BMessenger y por tanto cualquier objeto de estas clases es apto. El siguiente parámetro es la carpeta por defecto, que con NULL la dejamos a elección de Haiku. Luego indicamos que queremos abrir archivos, no carpetas ni enlaces simbólicos. Por último especificamos el ID del BMessage que enviará el panel. Esto nos servirá para después saber que ID tenemos que leer dentro de la función MessageReceived del BMessenger. Por último mostramos el panel para que el usuario decida el archivo a abrir. Si la acción es cancelada también será disparado el mensaje, tendremos que comprobar si el usuario eligió el archivo o cerró el diálogo.

Haiku File Panel

Leer la respuesta

Dentro de la función MessageReceived del BMessenger tenemos que accionar un caso especial si el ID del BMessage es el que hemos especificado en el panel.

void MiVentana::MessageReceived(BMessage* msg)
{
	switch(msg->what){
    	case READ_FILE: {
			if (msg->HasRef("refs")) {
	  			entry_ref ref;
	  			if (msg->FindRef("refs", 0, &ref) == B_OK) {
					BEntry entry(&ref, true);
					BPath path;
					entry.GetPath(&path);
					std::cout << "El archivo es " << path.Path() << std::endl; 
			 	}
			}
			break;
  		}
    }

}

Tenemos que comprobar si el mensaje tiene la propiedad “refs”. La propiedad “refs” la ajusta el File Panel cuando se ha seleccionado un archivo. Si la propiedad existe entonces lo leemos. Leeremos una entry_ref. Un entry_ref es una entrada dentro del sistema de archivos. Sin embargo esta estructura es de bajo nivel y no sabe exactamente donde se ubica. BEntry representa localizaciones dentro del sistema de archivos. Se construye con un entry_ref y esta clase ya sabe donde se ubica de forma legible por un humano (o un programador perezoso). Si queremos saber la ruta del archivo antes tendremos que crear un objeto vacío BPath que llenaremos con contenido. Finalmente la ruta, como string, la podremos leer llamando a la función Path dentro del objeto BPath.

Ya hemos visto como se usan los file panel en Haiku. Los file panel de guardar archivo se programan exactamente igual cambiando esa pequeña flag al principio.

Krita 3.0 permite trabajar con animaciones

Recientemente se ha lanzado la versión 3.0 de la aplicación de dibujo Krita, la cual se encuentra elaborada bajo la campaña KDE, la cual nos permite realizar todo tipo de trabajos con respecto a las gráficas, convirtiéndose en una gran alternativa a Adobe Photoshop, una herramienta muy importante la cual no tiene compatibilidad con todos los sistemas operativos vigentes. Hay que destacar que la

Jueves 02 de junio de 2016

Arte de código abierto

Hace un par de días hablábamos de la liberación de Krita 3.0, la magnífica herramienta de dibujo libre construida sobre herramientas Qt5 y KF5 y mencionábamos cómo el «kikstarter» de este año ha alcanzado sus objetivos en pocas semanas. El entusiasmo que genera Krita no vive solo en los usuarios «normales»: en enero del 2015 […]

Martes 31 de mayo de 2016

GUbuntu.es: El repositorio más rápido
GUbuntu.es: Bienvenido

Viernes 27 de mayo de 2016

José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

Cuentas de correo de “usar y tirar” o de un solo uso

correo Los correos electrónicos de un sólo uso son una gran herramienta para evitar el spam. Cuando queremos probar o evaluar un servicio para el que nos exigen una cuenta de correo electrónico y la evaluación no se hace efectiva mientras que no validemos dicha cuenta (por regla general haciendo click en un link que recibimos en la misma) lo más cómodo y práctico es recurrir a una de estas cuentas. Tienen, por supuesto, otros usos, pero mejor no te doy ideas por si acaso… 😉
Este tipo de correos tienen también una parte negativa, no lo olvides: la privacidad de lo que recibes en ellos es nula, puede que no puedas volver a usarlos en el futuro para recuperar la contraseña del servicio o, por el contrario, puede que alguien que no seas tu “suplante” tu personalidad a través de dicho correo y te robe la identidad en el servicio para el que la utilizaste en primer lugar… Así que ten mucho cuidado donde y para que las usas y trata de ser consciente de los riesgos que corres.

Allá por el año 2000 que fue cuando empecé a usar este tipo de cuentas e hice mi primera lista había apenas cinco servicios de este tipo. Ahora tengo listados más de 30. El único que sobrevive de aquellos tiempos es Mailinator…

No te voy a recomendar ninguno. Échales un vistazo por ti mismo. En esta lista encontrarás de todo: servicios con registro, sin él, que destruyen los correos en unos minutos, que los guardan para siempre, que te permiten elegir la cuenta o que la generan de forma aleatoria… Lo dicho, si necesitas algo así busca por ti mismo que es lo que mejor se ciñe a lo que quieres:

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: Cuentas de correo de “usar y tirar” o de un solo uso || Hospedado en un Cloud VPS de Gigas.
BlogDRAKE: Instalando Oracle 11gR2 XE y Oracle SQL Developer en Mageia, usando el escritorio XFCE

Jueves 26 de mayo de 2016

Adrián Arroyo

Tutorial de Hugo en español, generador de sitios estáticos

Los generadores de sitios estáticos son aplicaciones que dados unos ficheros generan un sitio web completo, listo para ser desplegado en Apache o Nginx. El generador es llamado bajo demanda del administrador por lo que, al contrario que en un CMS completo, este programa solo genera las páginas una sola vez, reduciendo considerablemente la carga de trabajo y el precio y aumentando en velocidad y rendimiento.

Página web de Hugo

Los generadores más populares son:

Nombre Lenguajde Plantillas Licencia Sitio web
Jekyll Ruby Liquid MIT http://jekyll.rb.com
Hexo JavaScript EJS y Swig MIT http://hexo.io
Hugo Go Go Template, Acer y Amber Apache http://gohugo.io
Pelican Python Jinja2 GPL http://blog.getpelican.com/

Además es también bastante conocido Octopress pero Octopress no es más que Jekyll con una colección de utilidades extra, el núcleo del programa sigue siendo Jekyll.

¿Por qué voy a elegir Hugo? Yo empecé con Jekyll y me gustó. Sin embargo Liquid no me acabó de convencer nunca y miré otras alternativas. Hexo me pareció excelente si lo que quieres hacer es un blog, funciona muy bien y es más rápido que Jekyll pero Jekyll tenía la ventaja de que se podía usar no solo en blogs, sino en cualquier web en general. Entonces oí hablar de Hugo. Hugo es el más rápido y el más flexible. No está enfocado solo en blogs, soporta todo lo que le eches. Sin embargo me parece que Hugo no es el más sencillo de configurar, así que aquí va el tutorial.

Instalando Hugo

Hugo está hecho en Go, quiere decir que está compilado y por tanto hay una versión diferente para cada sistema operativo. Descarga la versión de tu sistema operativo desde aquí. Si usas GNU/Linux es posible que tu distro haya empaquetado ya Hugo. Búscalo.

Una vez lo tengamos instalado comprobamos que todo esté en orden:

hugo version

Por defecto Hugo no trae ningún tema. Si quieres instalarte uno y no crear uno de cero puedes clonarlos desde Git. Si quieres probar los temas antes de instalarlos no dejes de mirar Hugo Themes

git clone --recursive https://github.com/spf13/hugoThemes ~/themes

Si queremos tener coloreado de sintaxis podemos usar Pygments. Si tienes PIP instalado es fácil.

sudo pip install Pygments

Además si quieres activar el autocompletado de Bash solo tienes que hacer

sudo hugo gen autocomplete
. /etc/bash_completion

Y con esto ya tenemos Hugo instalado correctamente. Ejecuta:

hugo new site MiSitioSupercalifragilisticoespialidoso

Hugo Themes

Organización en Hugo

En Hugo tenemos que tener muy en cuenta la organización de los ficheros. En primer lugar van los themes. Como puedes comprobar la carpeta themes generada esta vacía. Para ir probando los distintos temas puedes hacer un sencillo enlace simbólico entre la carpeta con los temas descargada y esta.

rmdir themes
ln -s ../themes .

Veamos el resto de carpetas:

  • archetypes. Arquetipos. Son plantillas para cuando añadimos un nuevo elemento. Por ejemplo, podemos tener un arquetipo de post sobre un vídeo de YouTube. Es posible crear un arquetipo que contenga configuración ya específica (categorías, reproductor insertado, etc) y que cuando escribamos ya lo tengamos medio hecho. A la hora de generar el sitio los arquetipos de origen no son tenidos en cuenta.
  • config.toml (o config.json o config.yaml). Este archivo contiene la configuración del sitio.
  • content. Aquí va el contenido central de la web. Dentro de content debes crear tantas carpetas como secciones tengas (aunque se puede sobreescribir vía configuración, es práctica recomendada). Cada sección tiene asignado un layout distinto. Dentro de la carpeta de cada sección la organización es libre, los archivos suelen ser de Markdown, pero HTML puro también vale.
  • layouts. ¿Cómo se organiza el contenido? Los layouts son la respuesta. Por cada sección hay que crear mínimo dos layouts, uno para mostrar un contenido solamente y otro para múltiples contenidos del mismo tipo (listas).
  • data. Aquí puedes almacenar archivos en JSON, YAML o TOML a los que puedes acceder desde Hugo. Estos archivos pueden contener cualquier tipo de información, piensa en ellos como en una especie de base de datos.
  • static. El contenido estático, imágenes, JavaScript, CSS, que no deba ser procesado por Hugo debes ponerlo aquí.

Configuración

Dentro del fichero config.toml hay que editar unos cuantos valores.

baseurl = "mi-sitio.com" # La dirección base del sitio
languageCode = "es-es" # El idioma de la web
title = "" # El título de la web
theme = "bleak" # El tema que se va a aplicar al contenido
googleAnalytics = "" # Código de seguimiento de Google Analytics
disqusShortname = ""

[Params] # A estos parámetros se puede acceder de forma directa con .Site.Params.NOMBRE
Author = "Adrián Arroyo"

También es configurable Blackfriday el motor de Markdown de Hugo, aunque las opciones por defecto son más que suficientes.

Creando contenido

Crea un archivo dentro de content. Puede estar dentro de una sección si así lo prefieres. En Hugo al igual que en Jekyll cada contenido tiene un front matter, es decir, los metadatos se añaden al principio en un formato que no se va a renderizar. Hugo soporta TOML, YAML y JSON. Si usamos TOML, los delimitadores del front matter serán +++, si usamos YAML --- y si usamos JSON tenemos que poner un objeto con las llaves, {}

+++
title = "El título de la entrada"
description = "Una pequeña descripción"
tags = ["hola","otra","etiqueta"]
date = "2016-05-23"
categories = ["Sobre el blog"]
draft = true
+++

Aquí va el contenido en Markdown o HTML que va a ser renderizado.

Podemos crear variables nuevas a las que podremos acceder desde .Params. Otras opciones predefinidas son type (que sobreescriben el valor de la sección), aliases (que permite hacer redirecciones), weight (la prioridad cuando el contenido sea ordenado) y slug (permite ajustar la URL del contenido).

Modificando el tema

Puedes modificar el tema usando la carpeta layouts. En el fondo un tema es una colección de layouts y recursos estáticos que son combinados con el tuyo. Si ya usas un tema y solo quieres realizar pequeñas modificaciones puedes editar el tema directamente. Si quieres añadir nuevas secciones o crear un tema de 0 entra a la carpeta layouts.

Hay varias subcarpetas dentro de layouts importantes:

  • _default. Es la que se usa cuando no hay otro disponible. Normalmente los temas sobreescriben esta carpeta. Si sobreescribes esta carpeta perderás el tema.
  • index.html. La página de entrada a la web
  • partials. En este carpeta se pueden guardar trozos HTML reutilizables para ser usados por los layouts.
  • shortcodes. Son pequeños trozos de HTML reutilizables con parámetros de entrada para ser usados por el contenido.

Dentro de cada layout (como en _default) tiene que haber mínimo dos archivos. Un archivo single.html que se usará cuando solo se tenga que representar una unidad de ese contenido y un archivo list.html que se usará cuando sea necesario mostrar un conjunto de esos contenidos.

Estos archivos han de programarse usando el motor de plantillas de Go y la API de Hugo. Un archivo single.html básico que muestra el título y el contenido tal cual sería así.


{{ partial "header.html" . }}
{{ partial "subheader.html" . }}
<section id="main">
  <h1 id="title">{{ .Title }}</h1>
  <div>
        <article id="content">
           {{ .Content }}
        </article>
  </div>
</section>
{{ partial "footer.html" . }}

Dentro de las páginas list.html es práctica habitual definir una vista li.html como un elemento individual. Esos elementos individuales se unen para formar la lista en list.html.

Algunos extras

Los shortcodes son pequeños trozos de HTML que aceptan parámetros. Podemos usarlos en el contenido. Piensa en ellos como Mixins de CSS o funciones de JavaScript. Por ejemplo, para marcar un resaltado de sintaxis:


<section id="mira-este-super-codigo">
	<p class="html-is-broken">Rompiendo el HTML</p>
</section>

O un enlace dentro de nuestra web: ```

```

Miércoles 25 de mayo de 2016

BlogDRAKE: Se extiende el plazo para el concurso de arte

Jueves 19 de mayo de 2016

Ramón Miranda

Ramón Miranda
Ramon Miranda

BTR. Diseño de Logotipo para Grupo de deportistas.

Hola a Todos! desde hace algún tiempo que vengo interesándome por el deporte a varios niveles y de ese interés nace la colaboración con el grupo BTR para el cual diseñé este logotipo. Os dejo con el resultado final y más adelante publicaré el making off que de seguro os va a sorprender

Logotipo BTR (Bike·Trail·Run) Formato Horizontal Banner y formato vertical

Y esta es la aplicación desarrollada para la camiseta.


Sergio García Mondaray

Sergio García Mondaray
yakiboo.net

Wedding Invitations Templates For Word 2016

Wedding Invitation Templates Word   Wedding Invitation Collection S8SxdIZq

Wedding Invitation Templates Word Wedding Invitation Collection

Free Wedding Invitation Websites   Wedding Invitation Collection 9G8KhxDr

Free Wedding Invitation Websites Wedding Invitation Collection

Example Of Wedding Invitation Card   Wedding Invitation Collection PoE7HUl3

Example Of Wedding Invitation Card Wedding Invitation Collection

Free Wedding Invitations Templates For Word 2016 wwwroselliacom lxwsmhfH

Free Wedding Invitations Templates For Word 2016 wwwroselliacom

wedding invitation background free download   weddingbackgroundclub 8aEESrcD

wedding invitation background free download weddingbackgroundclub

Wedding Invitation Templates Word Wedding Invitation Collection

Sergio García Mondaray

Sergio García Mondaray
yakiboo.net

Vintage Invitation Templates 2016

Free Download Templates For Vintage Wedding Invitations CNJzrUaO

Free Download Templates For Vintage Wedding Invitations

Vintage Graduation Invitation   Printable Graduation Announcement   A 5wJ3gBCw

Vintage Graduation Invitation Printable Graduation Announcement A

Vintage Wedding Invitations 2015 2016 Fashion 2016 eFZGJM6X

Vintage Wedding Invitations 2015 2016 Fashion 2016

2016 Cheap New Gold Wedding Invitations Vintage Hollow Lace Laser Cut x9q76JwK

2016 Cheap New Gold Wedding Invitations Vintage Hollow Lace Laser Cut

Simple Wedding Invitation Template Invitation Templates mHIyzaem dr6eLvZa

Simple Wedding Invitation Template Invitation Templates mHIyzaem

Free Download Templates For Vintage Wedding Invitations

Sergio García Mondaray

Sergio García Mondaray
yakiboo.net

Vintage Invitation Templates 2016

Free Download Templates For Vintage Wedding Invitations CNJzrUaO

Free Download Templates For Vintage Wedding Invitations

Vintage Graduation Invitation   Printable Graduation Announcement   A 5wJ3gBCw

Vintage Graduation Invitation Printable Graduation Announcement A

Vintage Wedding Invitations 2015 2016 Fashion 2016 eFZGJM6X

Vintage Wedding Invitations 2015 2016 Fashion 2016

2016 Cheap New Gold Wedding Invitations Vintage Hollow Lace Laser Cut x9q76JwK

2016 Cheap New Gold Wedding Invitations Vintage Hollow Lace Laser Cut

Simple Wedding Invitation Template Invitation Templates mHIyzaem dr6eLvZa

Simple Wedding Invitation Template Invitation Templates mHIyzaem

Free Download Templates For Vintage Wedding Invitations

Domingo 15 de mayo de 2016

Lakka: una distribución basada en videojuegos retro

Si eres fanático de los videojuegos retro, la distribución Lakka es la que debes tener instalada en tu ordenador con Linux, puesto que la misma nos permitirá tener acceso a juegos de 8 y 16 bits de una manera muy práctica. Esta distribución de Linux se caracteriza por estar basada en OpenELEC, un sistema operativo con excelentes epecificaciones como es el caso de la estabilidad y el buen

Viernes 22 de abril de 2016

José María Morales Vázquez

José María Morales Vázquez
tecnología – Un lugar en el mundo…

find, ejemplos de uso

chuleta El comando find es uno de los más útiles y versátiles de que disponen nuestros Linux. La potencia y la cantidad de opciones disponibles de esta utilidad es increible. Yo, que tengo una pésima memoria, tengo una chuletilla donde voy recopilando los más útiles que encuentro y/o he usado en alguna ocasión. Os copio aquí una selección y una pequeña introducción previa con los comandos más básicos para los novatos.

NOTA: Si no ejecutas el comando como root habrá muchos archivos y/o directorios a los que no tengas acceso y a los que, por tanto, el comando find no podrá acceder y no aparecerán en la lista. Aún como root es normal que en ocasiones te encuentres errores de acceso en determinados ficheros. Algo como esto:

find: «/proc/9308/task/9308/fd/5»: No existe el archivo o el directorio

NOTA (y II): Piensa que puedes combinar fácilmente entre si la mayoría de los ejemplos que veremos a continuación para obtener búsquedas aún más precisas.

Si queremos buscar un archivo de nombre archlinux.iso en nuestro equipo:

find / -name archlinux.iso

Si queremos restringir la búsqueda al directorio /opt (y todo lo que haya debajo):

find /opt -name archlinux.iso

En cualquiera de los casos anteriore podemos usar comodines en el nombre del archivo:

find / -name archlinux*.iso

Y si queremos que la búsqueda sea “insensible” a que el nombre del archivo (o la parte de este que especificamos) esté en mayúsculas o minúsculas:

find / -iname archlinux*.iso

Si sólo estamos interesados en encontrar directorios:

find / -type d -name log

Y sí sólo queremos encontrar ficheros:

find / -type f -name temp

Para encontrar archivos con distintos patrones (por ejemplo todos los iso y los tar.gz):

find /mnt/temp -type f \( -name *.iso -o -name *.tar.gz \)

O archivos que no cumplan un patrón (todos los que no sean iso):

find /mnt/temp/downloads -type f -not -name *.iso

Para encontrar archivos y directorios vacíos:

find / -empty

Para encontrar los ficheros que pertenecen a un determinado usuario:

find /opt -user josemaria

Para encontrar todos los ficheros con un determinado patrón cuyo contenido ha sido modificado por última vez hace exactamente tres días:

find /mnt/datos *.odt -type f -mtime 3

Idem pero modificados por última vez hace menos de 7 días:

find /mnt/datos *.odt -type f -mtime -7

Idem pero modificados por última vez hace más de un año:

find /mnt/datos *.odt -type f -mtime +365

NOTA: Si cambiamos mtime por atime en los tres ejemplos anteriores se realiza la búsqueda teniendo en cuenta el momento del último acceso al fichero y si usamos ctime se tiene en cuenta la última modificación no sólo del contenido del fichero sino también de sus atributos (propietario, permisos, etc.)

Para buscar los archivos con un determinado patrón y guardarlos comprimidos:

find /mnt/temp -type f -name *.txt | xargs tar cvzf textos.tar.gz

Para buscar los archivos con un determinado patrón y borrarlos:

find /mnt/temp -type f -name *.txt -exec rm {} \;

Para encontrar todos los archivos de más de 500 Megas:

find / -type f -size +500M

Idem al anterior pero mostrando el tamaño del archivo (en bytes) antes del nombre:

find / -type f -size +500M -printf '%s %p\n'

Para buscar los 10 archivos o directorios que más espacio ocupan:

find / | sort -nr | head -10

NOTA: ¿find o locate? La única ventaja de locate frente a find es que es más (mucho más) rápido, así que si realizas búsquedas a menudo y quieres que sean como centellas no te leas este texto que no es para ti. Las ventajas de find frente a locate son muchas otras (¡todas las demás que se te ocurran!). Y si no me crees leete esto.

Artículo Original: .

Este artículo pertenece a Un lugar en el mundo... Si quieres ver actualizaciones y comentarios interesantes visita el texto original en: find, ejemplos de uso || Hospedado en un Cloud VPS de Gigas.

Domingo 17 de abril de 2016

Liher Sanchez

Liher Sanchez
El blog de Liher

Que son los paquetes Snap en Ubuntu

Hoy he estado revisando varias noticias que tenia almacenadas en mis cuentas de email y me he encontrado con una de la que ya había leído algo pero no en profundidad. Esta noticia trataba sobre los paquetes Snap en Ubuntu, que son y las ventajas e inconvenientes que suponen y eso es de lo que os voy a hablar en este articulo.

Como muchos de vosotros sabréis la nueva versión LTS de Ubuntu, la 16.04, esta a la vuelta de la esquina y habrá varias novedades. Una de esas novedades es que los paquetes Snap harán su aparición en la versión de escritorio y conviviran junto con los Deb, pero ¿que son los paquetes Snap?

 

snap ubuntu

 

Hasta ahora cuando queríamos instalar un programa en Ubuntu o sus derivadas lo podíamos hacer de varias formas, desde el Centro de software, Synaptic y la Terminal pero todo se reduce a que Ubuntu se descarga el archivo instalable en formato Deb y lo instalaba en nuestro ordenador. Deb es el formato de paqueteria que se usa en Ubuntu y proviene de Debian. Os voy a explicar un poco a grandes rasgos como funciona. Supongamos que queremos instalar un programa llamado Gimp, accedemos al Centro de Software para instalarlo, lo buscamos y le damos al botón en el que pone “Instalar”, entonces se comprueba que en nuestro Ubuntu estén todos los programas o librerías de las que depende para instalarse el Gimp, si no están se descargan las necesarias y el propio Gimp, todo ello en formato Deb y después se instala. Esto tiene una ventaja clara, si un paquete sirve para varios programas lo pueden compartir, con el consiguiente ahorro de espacio en nuestro disco duro y RAM.

Snap es otro tipo de paqueteria que tiene como objetivo que cuando quieres instalar un programa viene todo lo necesario para dicho programa en un solo paquete, de esa forma evitaremos resolver las dependencias. Esto tiene una ventaja muy buena y es que como no necesitamos cumplir dependencias podremos tener la ultima versión del paquete Snap independientemente de la versión de Ubuntu que tengamos instalado. Ademas, como un programa empaquetado Snap tiene todo lo necesario para funcionar estará aislado del resto del sistema por lo que su repercusión en el sistema sera nula.

De momento convivirán los dos tipos de paqueteria, dudo mucho que a corto/medio plazo Ubuntu tenga previsto eliminar los Deb de su sistema operativo, aunque si que puede ser un primer paso para hacerlo en el futuro.

Una de las grandes desventajas que tiene Snap sobre Deb es que los programas ocuparan mas espacio en disco, aunque eso no es un problema con las capacidades de los discos duros de hoy en dia.

Un saludo.

Sábado 09 de abril de 2016

Raúl González Duque

Raúl González Duque
Linux – Mundo Geek

Ubuntu está en todas partes

Lleva años con nosotros, es una de las distros Linux más populares de la historia y hace poco hizo su desembarco en Windows. Hablamos de Ubuntu, cuya nueva versión estará disponible en un par de semanas y que, como el amor y los restaurantes McDonalds, está ya en todas partes.

Lo usa Netflix, Wikipedia, Dropbox, Instragram, Reddit, Snapchat y el mayor súper computador del mundo. Está en millones de PCs y servidores, en los coches de Google, y en la órbita terrestre, en la Estación Espacial Internacional.

Infografía 'Ubuntu está en todas partes'

Viernes 08 de abril de 2016

Ramón Miranda

Ramón Miranda
Ramon Miranda

Muses DVD preset Pack in bundle format for 2.9!



It is time for an update!
Recently some people asked for a bundle format so i have been working on making a bundle. If you like it, let me know..

Download here

Want to see some examples?



For newcomers i post some images and info about the set.
Here you have it.


The colors of the squares are only for differentiating the parts,  they don’t have nothing to be with the colour coding we designed for distinguishing the presets.
– Sketching:
This first part of the set covers the sketching and dry techniques phases like pencil, charcoal and hard pastel.
Usually you’d use these presets in black and white, but the advantage of the digital painting is that with only one preset you can still use all the colors you want, for instance to simulate the effect of color pencils.





– Digital:
This part of the set covers the most common presets that you need for digital painting. The classic round brushes with a good velocity in bigger sizes, smooth contour, squared… The illustration of below, for example, makes an extensive use of the squared brush for creating the structures of the mountain. After that, you will have to do a detailing finish, of course, but is a fast way for delimiting the contours.
Personally, I use these presets all the time.
– Ink & Fx:
In principle, this presets aren’t for inking comics (for that see the presets created by Timothee Giet), they are for doing studies or fast sketches. We can emulate the markers technique very easily.
– Oils & water:
I use this presets for creating the brushstrokes of wet paint, for giving the painting the look and feel of oil paint and gouache. They create expressive effects and they are fast but I don’t recommend the using them at really big sizes: you can easily saturate the resources of even a beefy computer. They use the “ascension” sensor for the color-rate.



– Blender:
This presets mix the color that is applied in the canvas. They are quite explanatory in themselves.
– Texturing:
This presets are used for fill big parts of the image with varied shapes like leaves, clouds, etc. They simulate effects that will take a lot of time painting it directly with normal round brush, saving us a lot of time that can be spent on places where we need manual detailing.


Download here

Bundle install

To install, download the file , then import it in Krita this way : Setting > Manage Ressources > Import Bundle/Resources.


License :  the brushkit itself and thumbnails is released under the WTFPL 2.0  (compatible with Public Domain and CC-0 ).
Ramón Miranda

Ramón Miranda
Ramon Miranda

Ramon Miranda Illustration. Diseño de Logotipo. Parte 2/2


Vamos a por la segunda parte de este post sobre la creación de mi logotipo.
(si no viste la primera y te apetece leer el artículo desde el inicio Aqui. http://www.ramonmiranda.com/2016/02/ramon-miranda-illustration-diseno-de.html)


  • Fase 3. De lápiz a Vectores
  • Fase 4. Tipografía
  • Fase 5. Prueba sobre soportes. 

Fase 3. De lápiz a vectores

Ahora es momento de ponerse en el ordenador teniendo una idea sólida sobre la que trabajar.
En esta fase voy a transformar lo que he hecho con el lápiz mediante un programa de vectores como inkscape, illustrator, corel draw. en esta ocasión Inkscape.
Voy a aprovechar una función que es la de trazar imágenes.  menú Path/trace Bitmap (shift+alt+b). Lo que hace es traducir cada contorno a un trazado vectorial. Como el diseño es simple y sin color se lo ponemos muy fácil. Aunque con color también puede hacer cosas muy interesantes pero eso lo dejamos para otro momento.
Trazado de imagen a vectores
No recomiendo dejar el trazado según salga de esa operación porque suele haber un exceso de nodos. Pero sí es un buen punto de partida para empezar a limpiar el trazado. ¡130 nodos son demasiados!
Nodos sin limpiar

En este caso concreto me gusta la sensación de "orgánico". Pero aun así decido probar a hacerlo puro vectorial partiendo de un cuadrado y dibujo de nodos. Se puede ver el proceso de izq a derecha. usando primitivas básicas y operaciones de unión, resta, puedo obtener rápidamente un resultado que parece más complejo. ¿pero funciona?...hmm.

Diseño Vector desde 0
No, no funciona porque he perdido la sensación de orgánico, parece algo muy frío y no me convence tanta frialdad. Tomo la decisión de desechar este camino y depurar el trazado anterior que guarda mejor la sensación orgánica del boceto.

Zonas a limpiar y resultado

Diseño limpiado de exceso de nodos.
Más tarde veré si quito algun nodo más sin perder esa sensación de "mancha" Si quito demasiados nodos se quedan las líneas planas.
Poniéndolos cara a cara este es el resultado
Orgánico vs Lineas puras

Fase 4. Tipografía

La elección de la tipografía tiene la misma importancia que el propio diseño del "logo" . Gracias a la fase de diseño en papel, ya se lo que busco en la tipografía. así que me lanzo a ello en Dafont.com. Quiero algo limpio, moderno, y con trazos muy concretos. ¿Lo encontraré? Después de ver 55 páginas de Dafont.com bajo la categoría de básico/sans serif. he seleccionado 10 que tienen licencias para poder usarlas libremente. o bajo condiciones aceptables.
10 primeras candidatas
Tras analizar cada palo, asta, altura de la x, interlineado etc... veo 5 que pasan a la siguiente fase.
Tipografías seleccionadas
Es duro dejar atrás unas fuentes tan bonitas pero hay claros indicativos de por qué no las elegí. Demasiado ángulo en su diseño,(picos en M y R) palos no redondeados, kerning que produce espácios ópticos que no me agradan, demasiado grosor, mi propio gusto o intuición...
Con las seleccionadas sigo cribando poco a poco
Proceso de selección de tipografía
Al final la elegida en el certamen "miss tipografia RM 2016 " es...
¡La Chata!
Crédito de la tipografía "la chata" para su creador. http://defharo.com/
Grácias Fernando por tan buen trabajo. Si buscais fuentes para vuestros proyectos personales o comerciales, Fernando es todo un profesional.
Información de logotipo

Y con esto ya tengo establecido todo el diseño de mi logo. Tamaños, relaciones fuentes, kerning... ¿y el color?
Color para una tinta
En el caso del color no he tenido muchos problemas porque sabía ya que iba a ser un tono cáĺido. Si a eso le sumamos el significado simbólico que le quiero dar pues ya está  os presento a #cc7722ff más conocido como ocre.

Desde el inicio de la humanidad hemos transmitido información a través de pinturas. El pigmento de la tierra es estable, duradero, y además nos ha acompañado durante todo la historia y todo lugar. Desde Egipto hasta el renacimiento y la actualidad. Ese para mí, es el color de la ilustración donde al final lo que hacemos es comunicar.

Y después de tener el color adecuado vamos a ver qué tal queda sobre fondos que ya tengo ganas de verlo en un uso real.
 Fase 5. Prueba sobre soportes
Con la tipografía ya elegida y todos los detalles definidos, me interesa ver como queda sobre diferentes soportes como por ejemplo fondos claros, fondos oscuros, y fondo de imagen. Esto me va a dar información para saber si mi diseño es versatil o me va a presentar algún problema que hasta ahora no haya visto. 
Lo primero a probar es una camiseta. Blanca y Negra.

Prueba simulación camiseta
Lo siguiente es probar con una imágen de fondo.
Prueba de logo sobre imagen


¡Y esto es todo por hoy! si te ha gustado no olvides compartir para que más personas lo vean, quizás le quites un dolor de cabeza a alguien. Comentadme lo que querais o preguntad si veis que algo no se explicó en su justa medida. 

Martes 22 de marzo de 2016

bq Aquaris M10 Ubuntu Edition, fechas confirmadas

El pasado 22 de febrero se presentó la bq Aquaris M10 Ubuntu Edition que como sabes es la  primera tablet...

La entrada bq Aquaris M10 Ubuntu Edition, fechas confirmadas aparece primero en Nosinmiubuntu | Ubuntu en concreto, GNU/Linux en general.

Domingo 20 de marzo de 2016

Liher Sanchez

Liher Sanchez
El blog de Liher

La realidad virtual, por fin, a la vuelta de la esquina

 

Después de pasar tiempo esperando lo que parecía su inminente llegada, la realidad virtual está  por fin al caer para cambiar nuestra experiencia de juego. Las gafas que nos trasladarán a otra realidad imaginaria dejarán pronto de ser un elemento de nuestra imaginación o de formar parte del atrezzo de películas como Existenz.

El último paso firme por la apuesta de este nuevo concepto de juego lo ha dado Sony con la presentación de PlayStation VR, las gafas de realidad virtual que funcionarán y dependerán de la PS4. La firma japonesa ha prometido un precio de lanzamiento de 399€, lo que indica que su punto de mira es el público masivo en comparación de otras gafas más caras como la Oculus Rift , que llegará en marzo y que se venderá por unos 750€ y la HTC Vive, las gafas de realidad virtual de gama más alta cuyo precio se calcula casi en los 900€.

Las gafas de Sony se esperan para el próximo mes de octubre y, por el momento, la marca nipona ha prometido unos 50 juegos compatibles para finales del 2016, bastantes menos que los que tendrán sus competidoras de gama alta que ofrecerán un catálogo mayor de juegos de PC.

La llegada de las gafas de realidad virtual conllevará un cambio necesario en el concepto y diseño de los juegos. En este sentido, podremos ver cómo se producen adaptaciones de muchos tipos de aventuras gráficas para satisfacer la nueva demanda que llega con la realidad virtual, en la que se busca una mayor inmersión en la experiencia de juego.

De los juegos de disparos en primera persona, pasaremos  a ser un personaje dentro de la historia, a hablar con los otros protagonistas o a interactuar con los objetos del escenario. Como podemos ver en el juego London Heist Getaway, nos convertiremos en atracadores cuyo cometido es salir con vida de la fechoría.

 

De poder interactuar con el crupier en la ruleta en vivo de algunos casinos online pasaremos a poder interactuar en los casinos de realidad virtual donde jugar, directamente, manipulando las máquinas de juego que llenan el espacio.

 

Algunos juegos se adaptarán a la realidad virtual ofreciendo una versión más realista de sí mismos. Con el juego Rock Band VR para las gafas Oculus, no habrá que imaginarse que uno es una rock star porque se podrá vivir la experiencia de serlo directamente encima del escenario.

 

Con la llegada de PS VR de Sony, el público mayoritario podrá tener acceso a este nuevo paso en la evolución de los videojuegos.  Pero seríamos ingenuos si pensásemos que las gafas de realidad virtual se quedarán solo en el ámbito del ocio.

Gracias a la realidad virtual, las marcas podrán ofrecer diferentes experiencias de inmersión antes de decidirnos por la compra de un producto, como poder ver detalladamente el interior de un coche o poder realizar una visita virtual antes de reservar una habitación de hotel.

Las compañías son conscientes del filón que se les presenta con la llegada de la realidad virtual y, por eso, no es de extrañar que las grandes tecnológicas ya estén invirtiendo en el desarrollo de negocios relacionados con este ámbito. Apple ya ha fichado a expertos en la materia para el desarrollo de sus propias gafas y Alphabet (Google) tiene su propio departamento para el desarrollo de unas gafas que funcionen con móviles Android.

Todos se apuntan a esta nueva realidad que cambiará nuestra forma de interactuar con nuestro alrededor. La última en anunciar que quiere formar parte del cambio ha sido Sony con sus gafas pro más económicas. Aunque si los 399€ que cuestan sigue pareciéndote caro, hay oferta para todos los bolsillos incluidas gafas de realidad virtual por menos de 50€.

 

Sábado 19 de marzo de 2016

Juanjo Amor

Juanjo Amor
DrAmor's Blog

¡Cifremos la web!

Qué es Let’s Encrypt

Es bien sabido que conviene cifrar siempre que podamos, y la web no lo es menos. De hecho, hace tiempo que Google fomenta el uso de web cifrada amenazando con penalizar aquellas que no lo estén.

El caso es que, para tener una web cifrada, tenemos dos problemas: por un lado, comprar un certificado a una entidad certificadora reconocida, y por otro, renovarlo periódicamente (lo que suele tener un coste también). Desde hace tiempo, iniciativas como CaCert, intentaron crear una autoridad certificadora libre de costes para sus usuarios y gestionada por la comunidad, de la que, pese a ser yo mismo uno de sus notarios, tengo que decir que su éxito ha sido siempre escaso, entre otras razones porque lleva ya bastantes años con nosotros y aún no es reconocida por la mayoría de los navegadores.

Por otro lado, la renovación tiene otro problema: hay que estar pendiente de ello. Para resolver ambos problemas, ha surgido una iniciativa, llamada Let’s Encrypt.

Let's Encrypt

Lo primero que vemos es que la reconocen todos los navegadores. El coste de conseguir esto debe estar cubierto por la multitud de sponsors que tiene el proyecto.

En segundo lugar, utiliza un desafío, llamado ACME, para verificar que la web que queremos cifrar es la dueña del dominio a usar (por ejemplo, https://dramor.net/). Con esta verificación, se pueden emitir sin problemas, certificados sin coste (al ser generados automáticamente), siempre que no necesitemos otras características como la validación de identidad.

Veremos que con este proyecto, se pueden conseguir certificados de sitio web de forma bastante sencilla. Por ejemplo, veamos cómo se resuelve para Nginx.

Implementación en los sitios de DrAmor.net

Antes de nada, decir que no voy a dar la configuración completa de nginx, entendiendo que el lector sabrá de lo que hablo, o podrá ayudarse de los tutoriales mencionados en este artículo.

En general, lo que veremos nos vale en cualquier Linux o Unix que pueda ejecutar git, python y nginx. Lo primero que haremos es bajarnos el repositorio de Let’s Encrypt:

$ git clone https://github.com/letsencrypt/letsencrypt

Este repositorio trae plugins para varios servidores web, pero como Nginx no está aun bien soportado, debemos usar el plugin webroot.

Hemos seguido la documentación oficial y el tutorial de Digital Ocean para hacernos una idea, aunque los pasos seguidos fueron, en primer lugar crear un fichero de configuración llamado /etc/letsencrypt/letsencrypt-dramor.net.ini:

rsa-key-size = 4096

email = Direccion-email-valida@gmail.com

webroot-map = {"dramor.net,www.dramor.net":"/var/www/dramor.net", "blog.dramor.net,www.blog.dramor.net":"/var/www/dramor_blog", "home.dramor.net":"/var/www/dramor_home"}

Por supuesto, el e-mail debe ser correcto. Lo oculto con el ánimo de evitar un poco el spam, claro. Y el webroot-map no es más que un formato json donde especifica los dominios a firmar, junto con la carpeta raíz de cada sitio, que debe incluir una subcarpeta publicada por nginx, para poder ejecutar el desafío ACME.

La carpeta a publicar en nginx se debe llamar .well-known. Por ejemplo, la podemos publicar en los sitios virtuales nginx con:

location ~ /.well-known {
    allow all;
}

Una vez configurado nginx, ya podemos generar los certificados:

$ cd letsencrypt

$ sudo ./letsencrypt-auto certonly -a webroot --renew-by-default --config /etc/letsencrypt/letsencrypt-dramor.net.ini
Checking for new version...
Requesting root privileges to run letsencrypt...
   sudo /home/jjamor/.local/share/letsencrypt/bin/letsencrypt certonly -a webroot --renew-by-default --config /etc/letsencrypt/letsencrypt-dramor.net.ini

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/dramor.net/fullchain.pem. Your cert will
   expire on 2016-06-16. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
 - If you like Let's Encrypt, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

La primera vez creará un virtualenv de la versión de Python requerida, y actualizará algunos paquetes. Una vez generados los certificados, se instalan en: /etc/letsencrypt/live/dramor.net. Si dio algún error, debemos revisar que esté accesible .well-known en los sitios virtuales de nginx, y que los DNS del dominio deseado apunten correctamente al servidor web, entre otras cosas. Los mensajes de error siempre son lo suficientemente descriptivos como para no requerir más explicación. Por ejemplo, nos puede avisar de que algún nombre DNS del dominio a asegurar no resuelve correctamente el registro A o CNAME, o no apunta a nuestro servidor.

Usar los certificados en Nginx ya es cosa de usar las líneas de configuración de nginx similares a:

ssl_certificate /etc/letsencrypt/live/dramor.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dramor.net/privkey.pem;

Renovación automática

Los certificados así generados tienen una vigencia de solo tres meses. Pero renovarlos consiste simplemente en volver a ejecutar el desafío ACME.

Para ello, solo hay que llamar a letsencrypt-auto con otro parámetro:

$ ./letsencrypt-auto renew

Podemos hacer un script a ejecutar periódicamente (por ejemplo, un cron semanal), que realice esta acción y a continuación ejecute un reload de nginx. De este modo, podemos olvidarnos de las renovaciones: tendrán lugar cuando hagan falta.

Conviene probar todos los scripts antes de automatizarlo con el cron. Por ejemplo, si nada más generar los certificados intentamos renovarlos:

$ ./letsencrypt-auto renew
Checking for new version...
Requesting root privileges to run letsencrypt...
   sudo /home/jjamor/.local/share/letsencrypt/bin/letsencrypt renew
Processing /etc/letsencrypt/renewal/dramor.net.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/dramor.net/fullchain.pem (skipped)
No renewals were attempted.

Podemos forzar la renovación para verificar que funciona, con:

$ ./letsencrypt-auto renew --force-renewal

Por último, indicar que si vamos a hacer muchas pruebas, mejor generemos los certificados con la opción staging, para que que se generen certificados no válidos. Si hacemos muchas pruebas seguidas, alcanzaremos fácilmente el límite diario y no podremos generar más hasta el día siguiente.

Si hemos hecho todo correctamente, podremos navegar por el sitio web con cifrado; y si queremos, podemos comprobar la calidad del mismo aquí: SSLLabs. Conseguir una buena puntuación ya es cosa de seguir determinadas buenas prácticas con el servidor web, que no cubriré aquí.

Martes 15 de marzo de 2016

Liher Sanchez

Liher Sanchez
El blog de Liher

Cuales son los mejores moviles chinos

Ya llevo un mes y medio con mi nuevo Xiaomi Redmi Note 3 y sigo estando muy contento con el. Desde hace tiempo hablo con amigos y conocidos acerca de los móviles chinos y muchos de ellos todavía son muy reacios a comprar un terminal de esta procedencia, y la verdad es que no se la razón.

Si que es verdad es hay móviles chinos que son malos, y muchos, pero también los hay muy buenos, puedo dar fe de ello. No me considero con fanático de los móviles y no estoy muy al día pero que me he informado un poco sobre los móviles chinos y creo que tener algo de base para emitir una opinión medianamente valida, de hecho cuando me propuse adquirir mi actual teléfono estuve leyendo bastante sobre las distintas marcas.

Después de todo lo que leí en Internet me quede con una seria de marcas que son una referencia en cuanto a móviles chinos se refiere, estas marcas son:

  • Xiaomi
  • Meizu
  • Huawei

Por supuesto que hay muchas mas marcas que son muy buenas, pero a mi entender las tres que he citado son una garantía de calidad, ademas las tres tienes móviles que relación calidad/precio son de lo mejorcito que puedes encontrar. Ademas, si te mueves un poco por paginas del sector como Andro4all, donde tienen muy buenas reviews de terminales, veras que esas marcas gozan de prestigio. Repito que hay mas marcas de mucha calidad, no quiero que nadie piense que porque no las he citado no piense así, pero yo me decanto por esas. Pongo un ejemplo, Apple hace terminales de mucha calidad pero yo no compraría un Iphone, y eso no quiere decir que yo piense que son malos, pero no compraría uno ya que los precios que tienen me parecen tremendamente inflados y no me va el secretismo con respecto sus especificaciones.

 

moviles-chinos-son-rentables-L-Mq8kC1

 

Saber cuales son los mejores móviles chinos es bastante complicado, hay que tener en cuenta lo que un usuario se quiere o puede gastar en un terminal. Si dispones de 300 euros puedes tener un Xiaomi Mi5, que es un autentico pepinaco de móvil, pero no todos se quieren gastar ese dinero. Sin embargo tienes un Meizu M2 Note por unos 130/140 euros, la relación calidad precio esta muy muy bien. Hay muchísimos artículos y paginas que hablan y mucho sobre estos terminales y que están mas especializados en el tema, os dejo un enlace a un articulo que me pareció interesante, hablan sobre los mejores moviles chinos baratos y habla de varias marcas, me parece un muy buen punto de partida.

Hay muchísima información en Internet y es obvio que el hecho de tener tiendas en las que podamos “palpar” estos teléfonos antes de comprarlos puede empujarnos a dar el salto. Desde luego que yo estoy muy contento después de haber cambiado, por ahora lo único que me queda por comprobar es la durabilidad del teléfono Xiaomi que tengo, pero si os puedo asegurar una cosa, es duro. Yo soy muy torpe y se me ha caído en varias ocasiones de la mano y no tiene ni un rasguño ni se le ha roto nada.

Por supuesto que si hacéis como yo hice una vez que compre un móvil chino con apariencia estética al Iphone 4 por 22 euros en una tienda china de Internet no podéis esperar gran cosa, pero hay que tener en cuenta una serie de cosas:

  • Era un teléfono con dual sim
  • Tenia cámara de fotos
  • Tenia radio y televisión analógica
  • Admitía tarjeta microsd
  • Venia con dos baterías

Y funcionaba, se lo preste a un familiar y se rompió, pero iba bien. Vete aquí a una tienda y dile que quieres un móvil por 22 con cámara de fotos. Esto no quiere decir que fuese un móvil bueno, pero por ese precio ¿que puedes pedir?

Un saludo.

Miércoles 09 de marzo de 2016

MD5sum: comprueba la integridad de una ISO

Cuando descargas una ISO, por ejemplo de tu distribución favorita o de una ROM de Android, antes de  instalarla en...

La entrada MD5sum: comprueba la integridad de una ISO aparece primero en Nosinmiubuntu | Ubuntu en concreto, GNU/Linux en general.

Domingo 06 de marzo de 2016

Curso: Desarrollo en HTML5, CSS y Javascript de Apps Web, Android e iOS

Ya hemos hablado en la web acerca de otros cursos gratuitos e interesantes que podían ayudarte a ampliar tu formación...

La entrada Curso: Desarrollo en HTML5, CSS y Javascript de Apps Web, Android e iOS aparece primero en Nosinmiubuntu | Ubuntu en concreto, GNU/Linux en general.

Sábado 05 de marzo de 2016

Alvaro del Castillo

Alvaro del Castillo
Entorno de acs

Configuración de WordPress

Después de varios días por fin saco tiempo para continuar la entrada del otro día donde os comentaba las bondades de WordPress. Hoy voy a daros algunos consejos sobre como configurarlo:

1. Estructura Permalink

Lo primero que debes cambiar es la estructura de enlaces permanentes. Se encuentran en Configuración → Enlaces permanentes. El enlace permanente por defecto es <postid>, pero yo prefiero utilizar el nombre de la entrada:

/%postname%/

Permalinks

2. ¿SSL o no SSL?

En 2014 Google anunció que las webs corriendo bajo https tendrían mejor valoración de cara al posicionamiento por este motivo muchas web han cambiado a SSL. Todo depende de nuestro presupuesto, los SSL cuestan $$$.

3. ¿WWW vs no-WWW?

Aquí es cuestión de gustos, si quieres que tu blog aparezca en el navegador como como www.example.com o simplemente example.com. Asegúrate de que en Configuración → General, la versión que deseas aparece correctamente.

4. Optimiza las descripciones

Los webmaster suelen centrarse en los títulos pero nunca hay que dejar de lado las descripciones. La descripción muestra una parte de información muy importante en los resultados de búsqueda y podemos incluir en ella las palabras clave (keywords) que queremos resaltar.

5. Limpiar el código

Reduce al mínimo posible los Javascript y CSS que pueda tener tu plantilla. Google valora la rapidez de carga de tu web, de hecho hay un test específico para ello que mide tanto la versión normal como la móvil (responsive):

Test de velocidad de carga de Google

6. SEO y contenido duplicado

Debes huir siempre del contenido duplicado ya que es una de las cosas que más penalizan a la hora de posicionar tu blog. Google tiene avanzados algoritmos que analizan el texto (densidad keywords, frases, párrafos, incluso el conjunto!) para ver si son copiados de otros existentes.

7. Encabezamientos (headers)

Aunque cada vez tienen menor peso en el SEO aún sigue siendo una buena idea poner algunos textos con encabezamientos, por ejemplo el de mayor tamaño <h1> para el nombre de la entrada. Puedes poner también algún <h2> y <h3> para slogan o títulos secundarios.

 

Lunes 08 de febrero de 2016

Alvaro del Castillo

Alvaro del Castillo
Entorno de acs

WordPress SEO

Con la invención de Internet y el marketing digital el alcance de la optimización de motores de búsqueda (SEO) se ha convertido en uno de los métodos preferidos de promoción web. Por este motivo en la entrada de hoy quiero hablaros de como utilizar el software de blogs más conocido del mundo (WordPress) para mejorar el SEO de vuestras webs.

SEO, en términos generales se denomina como la optimización de motores de búsqueda. A diario millones de personas utilizan los buscadores para acceder a la información que necesitan. Aparecer en las primeras posiciones de las palabras clave (keywords) es imprescindible para el éxito de nuestro proyecto en Internet. Por este motivo la mayoría de los webmasters han optado por la promoción basada en SEO para poder llegar a su público objetivo.

Con el paso de los años (incluso meses) las técnicas de optimización en buscadores se actualizan por lo que hay que estar atentos y en constante evolución ante los cambios del algoritmo de Google.

Recientemente la empresa donde alojo ACS (podeis ver su banner al pie del blog) ha lanzado un VPS específico para el SEO basado en WordPress.

¿Y por qué han elegido WordPress?

WordPress es uno de los mejores sistemas de gestión de contenido cuando se trata de SEO, teniendo en cuenta que casi una cuarta parte de las webs de internet están hechas con este CMS tantos webmasters no han podido equivocarse!.

Ahora al grano, lo que proponen con este VPS SEO es poder levantar en pocos minutos hasta 4 hosting WordPress cada uno con una dirección IP clase C propia (IPs españolas).

WordPress es un software muy bien optimizado y permite que cada página sea indexada rapidamente por los buscadores, por este motivo es muy sencillo crear un blog, añadir buen contenido y enlazar a nuestras webs para mejorar sus rankings.

Miércoles 03 de febrero de 2016

Alberto Ruiz

Alberto Ruiz
Silicon Island

This blog has moved to Wordpress.com

I've moved my blog, you can read my new posts here https://siliconislandblog.wordpress.com/

Pedro L. Lucas

Pedro L. Lucas
Cartas de Linux

Adapt: La forma sencilla de instalar paquetes de otra versión de Ubuntu

Adapt es un programa que permite instalar paquetes de otras versión de Ubuntu en la versión que tengamos instalada. Se pueden instalar paquetes de una Ubuntu 15.10 en una Ubuntu 14.04, por ejemplo. Todo esto funciona gracias a contenedores que descargan una versión de la distribución que se haya elegido.

Si queréis saber más sobre adapt os recomiendo leer la siguiente presentación realizada por Dustin Kirkland:

http://people.canonical.com/~kirkland/SCALE%2014x-%20adapt%20install%20anything.pdf

¿Por qué puede ser útil?

La mayoría de las personas tratan de usar las versiones estables de Ubuntu, las LTS. Esto significa que vamos a trabajar con versiones de los programas “estables”. Es decir, que si nuestra Ubuntu 14.04 viene con la versión 4.2 de LibreOffice, aunque salga la versión 5 de LibreOffice, las actualizaciones sólo nos van a permitir instalar la versión 4.2. A no ser que instalemos LibreOffice desde los backports, desde un ppa o bajando el instalador de LibreOffice, seguiremos siempre con la misma versión 4.2 de LibreOffice.

Esto es cierto para casi todos los paquetes de la distribución. Por ejemplo, Firefox sí se actualiza a la última versión que salga, pero LibreOffice no. Esto es así por motivos de seguridad.

Esta forma de gestionar las versiones se hace por estabilidad de la distribución, que es algo muy deseable en servidores, pero puede resultar fustrante para el usuario doméstico.

Si queremos estar siempre a la última, tenemos dos opciones, pasarnos a una distribución rolling-release (que instala siempre las últimas versiones de los programas) o intentamos instalar los paquetes por otros medios.

Ahora aparece adapt que instala un contenedor y dentro de ese contenedor descarga la versión que necesitemos de Ubuntu. Las aplicaciones se ejecutarán dentro de dicho contenedor.

Un contenedor es una forma de virtualización que simplemente le dice a los programas vais a estar confinados dentro de este espacio en el disco duro, vais a poder usar estas conexiones de red, podéis usar estos recursos de CPU y ¡tenéis prohibido salir de ahí! Evidentemente lo que vayamos a ejecutar dentro del contenedor tiene que estar adaptado a funcionar en ese entorno. Es fácil darse cuenta que un contenedor va a usar menos recursos que una máquina virtual de VirtualBox y podemos tener miles funcionando en un servidor.

Para saber más sobre la magia de los contenedores:

https://es.wikipedia.org/wiki/LXC

http://www.ubuntu.com/cloud/lxd

https://wiki.gentoo.org/wiki/LXD