Weblogs Código

Variable not found

¡Últimos días para obtener tu libro gratis de O'Reilly!

July 01, 2016 05:28 AM

Promoción finalizada. Muchas gracias a los más de mil lectores que habéis participado!

¡Consigue un libro gratis de O'Reilly!Pues casi ha pasado un mes desde que lanzamos esta iniciativa, y ya se cuentan por centenares los seguidores de Variable not found que han descargado su libro electrónico de O'Reilly, totalmente gratis.

Sólo quería recordaros que la promoción finaliza el próximo 30 de junio (no sé si ese día aún se podrá, así que, por si acaso, mejor que asumáis que no).

Por si no os enterasteis en su momento, estamos hablando de que para celebrar el aniversario del blog, O'Reilly regala a todos los lectores un libro en formato electrónico, a elegir entre estos diez títulos de programación, o un vídeo-tutorial sobre Web API:

Mastering Cross-Platform Development with Xamarin Mastering Cross-Platform Development with Xamarin
By Can Bilgin
Más info
C# 6 and .NET Core 1.0: Modern Cross-Platform Development C# 6 and .NET Core 1.0: Modern Cross-Platform Development
By Mark J. Price
Más info
jQuery Essentials jQuery Essentials
By Troy Miles
Más info
C# 6.0 in a Nutshell C# 6.0 in a Nutshell, Sixth Edition
By Joseph Albahari & Ben Albahari
Más info

CSS: The Missing Manual CSS: The Missing Manual, Fourth Edition
By David Sawyer McFarland
Más info
Learning NHibernate 4 Learning NHibernate 4
By Suhas Chatekar
Más info
Learning .NET High-performance Programming Learning .NET High-performance Programming
By Antonio Esposito
Más info
Code-First Development with Entity Framework Code-First Development with Entity Framework
By Sergey Barskiy
Más info
AngularJS: Up and Running AngularJS: Up and Running
By Shyam Seshadri, Brad Green
Más info
Concurrency in C# Cookbook Concurrency in C# Cookbook
By Stephen Cleary
Más info
RESTful Services with ASP.NET Web API Vídeo (2h): RESTful Services with ASP.NET Web API By Fanie Reynders
Más info

Además, O'Reilly ofrece a los lectores de Variable not found descuentos del 40% en libros en papel, y de 50% en libros electrónicos y video training utilizando el código PCVW al realizar la compra.

¿Y cómo podéis conseguir vuestro regalo?

Recordad que tenéis hasta el próximo 29 de junio de 2016 para obtener vuestro regalo. Sólo tenéis que lo siguiente:
  • Ayudarme a difundirlo para darle el mayor alcance posible, pues estaréis contribuyendo a que más personas puedan conseguir su regalo. Por tanto, os agradecería mucho:
              
    • Que lo comentéis con vuestros compañeros, amigos y conocidos que aún no se hayan beneficiado de esta iniciativa.
       
    • Que publiquéis en vuestra cuenta de Twitter, Facebook u otras redes sociales un enlace hacia este post. Por ejemplo, estaría bien algo como lo siguiente, aunque podéis demostrar vuestra creatividad y poner otras cosas siempre que vayan en la dirección de los objetivos propuestos :)
      Sólo HOY, @oreillymedia te regala un e-book por ser seguidor de @variablnotfound. ¡Ve a por el tuyo! http://bit.ly/295LSAJ
    • O, como mínimo, para los más perezosos, que retuiteéis en Twitter o compartáis en vuestras redes sociales los mensajes de otras personas que ya lo hayan publicado.
       
  • Si os apetece estar informados de las novedades del blog, seguir la nueva cuenta del blog en Twitter, @variablnotfound. A largo plazo pretendo que sea un canal exclusivo para el blog, separándolo de mi cuenta personal @jmaguilar.
     
  • Finalmente, reclamar vuestro libro o vídeo utilizando este enlace: http://oreil.ly/1W9VAFL. El proceso es muy simple: tendréis que registraros como usuario, elegir el contenido que os interese (uno por persona), y en pocas horas tendréis acceso al mismo.
¡¡No perdáis la oportunidad, que se acaba!!

Publicado en Variable not found

» Leer más, comentarios, etc...

Variable not found

Por el aniversario de VariableNotFound, ¡O'Reilly te regala un libro!

July 01, 2016 05:27 AM

Promoción finalizada. Muchas gracias a los más de mil lectores que habéis participado!

¡Seguimos dándolo todo con motivo del décimo aniversario de Variable Not Found! Acabamos de finalizar el último sorteo y ya vamos a por lo siguiente, que os adelanto que os va a encantar :)

Seguro que no necesitáis que os presente a O'Reilly, pues se trata de una de las compañías de referencia en la difusión de contenidos para desarrolladores en forma de libros, eventos y cursos en vídeo desde hace más de veinte años.

Pues bien, O'Reilly ofrece a los lectores de Variable not found descuentos del 40% en libros en papel, y de 50% en libros electrónicos y vídeo cursos utilizando el código PCBW al realizar la compra. Interesante propuesta, ¿eh?

Pero no acaba ahí la cosa... :)

O'Reilly quiere celebrar con todos nosotros el aniversario regalando a todos los lectores del blog un libro en formato electrónico, a elegir entre los siguientes diez títulos de programación, o un vídeo-tutorial sobre Web API.

Mastering Cross-Platform Development with Xamarin Mastering Cross-Platform Development with Xamarin
By Can Bilgin
Más info
C# 6 and .NET Core 1.0: Modern Cross-Platform Development C# 6 and .NET Core 1.0: Modern Cross-Platform Development
By Mark J. Price
Más info
jQuery Essentials jQuery Essentials
By Troy Miles
Más info
C# 6.0 in a Nutshell C# 6.0 in a Nutshell, Sixth Edition
By Joseph Albahari & Ben Albahari
Más info

CSS: The Missing Manual CSS: The Missing Manual, Fourth Edition
By David Sawyer McFarland
Más info
Learning NHibernate 4 Learning NHibernate 4
By Suhas Chatekar
Más info
Learning .NET High-performance Programming Learning .NET High-performance Programming
By Antonio Esposito
Más info
Code-First Development with Entity Framework Code-First Development with Entity Framework
By Sergey Barskiy
Más info
AngularJS: Up and Running AngularJS: Up and Running
By Shyam Seshadri, Brad Green
Más info
Concurrency in C# Cookbook Concurrency in C# Cookbook
By Stephen Cleary
Más info
RESTful Services with ASP.NET Web API Vídeo (2h): RESTful Services with ASP.NET Web API By Fanie Reynders
Más info

Tanto libros como vídeos son en inglés, pero supongo que esto no será impedimento para sacarles partido, ¿verdad? ;)

¿Y cómo podéis conseguir vuestro regalo?

Los que estéis interesados (¡todos, supongo! ;D) tenéis hasta el próximo 30 de junio de 2016 para obtener vuestro regalo. Sólo tenéis que lo siguiente:
  • Ayudarme a difundirlo para darle el mayor alcance posible, pues estaréis contribuyendo a que más personas puedan beneficiarse de la oferta del patrocinador. Por tanto, os agradecería mucho;

    • Que publiquéis en vuestra cuenta de Twitter, Facebook u otras redes sociales un enlace hacia este post. Por ejemplo, estaría bien algo como lo siguiente, aunque podéis demostrar vuestra creatividad y poner otras cosas siempre que vayan en la dirección de los objetivos propuestos :)
      Sólo hasta el 29 de junio, @oreillymedia te regala un e-book por ser seguidor de @variablnotfound. ¡Ve a por el tuyo! http://bit.ly/1Rhu7d4
    • Que publiquéis en vuestros blogs o páginas una breve reseña de esta iniciativa, con su enlace correspondiente a este post.
       
    • O, como mínimo, para los más perezosos, que retuiteéis en Twitter o compartáis en vuestras redes sociales los mensajes de otras personas que ya lo hayan publicado.
       
  • Si os apetece estar informados de las novedades del blog, seguir la nueva cuenta del blog en Twitter, @variablnotfound. A largo plazo pretendo que sea un canal exclusivo para el blog, separándolo de mi cuenta personal @jmaguilar.
      
  • Finalmente, reclamar vuestro libro o vídeo utilizando este enlace: http://oreil.ly/1W9VAFL. El proceso es muy simple: tendréis que registraros como usuario, elegir el contenido que os interese (uno por persona), y en pocas horas tendréis acceso al mismo.
Y por último, me gustaría agradecer a O'Reilly el interés mostrado por participar en esta celebración, y su impresionante contribución para hacerla aún más grande.

¡Que aproveche! Y seguid atentos al blog, porque adicionalmente todas las semanas estamos repartiendo regalos impresionantes :)

Publicado en Variable not found

» Leer más, comentarios, etc...

Variable not found

Último sorteo: ¡subscripciones a Resharper Ultimate!

June 29, 2016 06:45 AM

Resharper Ultimate, de JetBrainsHoy comenzamos el último sorteo de la celebración del aniversario del blog, unas semanas en las que hemos repartido de todo, gracias a nuestros patrocinadores y amigos. Pero si hay una compañía que no podía faltar en esta celebración, esa era JetBrains, líderes indiscutibles en herramientas para desarrolladores.

Personalmente le tengo bastante aprecio a estos chicos desde que conocí su popular Resharper, una herramienta que uso a diario desde hace años, por lo que no dudé en contactar con ellos y, por supuesto, se ofrecieron amablemente a colaborar en la celebración.

Y gracias a ello, hoy sorteamos dos suscripciones a Resharper Ultimate, la suite de productos que incluye:
  • Resharper para .NET. Indispensable. Creedme, una vez lo probéis os haréis adictos ;)
  • Resharper para C++.
  • DotTrace el profiler de rendimiento para .NET
  • DotMemory, un profiler de memoria para aplicaciones .NET
  • DotCover, runner de pruebas unitarias y control de cobertura de código
  • DotPeek, el descompilador para.NET (que por cierto, de todas formas es gratuito y podéis descargar desde su página).
Sin duda, un pack de categoría.

¿Y cómo participo en el sorteo?

Pues por ser el último sorteo, vamos a simplificar las reglas de participación:
  • Para participar sólo tenéis que escribir un comentario en este post del blog, lo que queráis; sólo os pido que seáis simpáticos y corteses ;D Pero sobre todo, incluid alguna vía para que pueda contactar con vosotros si sois los afortunados.
     
  • Opcionalmente, os invito a seguir la cuenta @variablnotfound en Twitter para estar al tanto de lo que se cuece en el blog.
¡Y eso es todo! Esta vez todos participaréis en igualdad de condiciones :)

¿Cuándo se realiza el sorteo?

Este último sorteo se realizará el próximo domingo 3 de julio. Todos los comentarios que entren a partir del sábado a las 23:59 UTC+2 serán eliminados como penalización por dejarlo para última hora ;D

Ese día, una aplicación extraerá automáticamente dos comentarios del post, cuyos autores serán los ganadores de las licencias. Me pondré personalmente en contacto con los afortunados a través de las vías que hayan indicado al participar, pero, si por cualquier motivo no fuera capaz de contactar con alguno de ellos en un tiempo razonable, el premio sería sorteado de nuevo entre el resto de participantes.

Ale, ya podéis ir participando. Y si os toca Resharper, recordad: ¡cuidado, que engancha! ;D

Publicado en Variable not found

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

asm.js

June 29, 2016 06:12 AM

Recuerdo haber leído sobre asm.js, hace como un par de años. Quizás atraído por su nombre, mezclando ensamblador y Javascript. No me pareció nada relevante en su momento, pues además, sólo estaba adoptado en Firefox. Os voy a contar la esencia de asm.js, y vosotros decidiréis. asm.js es un subconjunto de Javascript, es decir, cualquier [...]

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

Salesforce, Microsoft Dynamics y ZOHO

June 29, 2016 03:31 AM

 

Con 10 años de experiencia implementando CRM, las mejores plataformas del mercado Salesforce, Microsoft y ZOHO

» Leer más, comentarios, etc...

Ingenieria de Software / Software Engineering / Project Management / Business Process Management

CRM Dynamics Field Service and IoT

June 29, 2016 03:19 AM

Evolucionando el tema de IoT y cada vez con mas aplicaciones para CRM, en este caso Field Service

 

CRM and IoT

» Leer más, comentarios, etc...

PHP Senior

Zend Framework 3 disponible!

June 28, 2016 06:45 PM




We are excited to deliver the latest release of Zend Framework, the first major release in four years.

Zend Framework 3, along with recent releases of Zend Server 9 and Zend Studio 13.5, makes it easier for you to develop, debug, monitor, and deploy modern web and mobile apps in PHP 7.

Zend Framework 3 includes:
  • Increased performance – up to 4X faster applications under PHP 5, and even better using
    PHP 7
  • PHP 7 support
  • Improved documentation for each component repository
  • Expressive, a PSR-7 middleware microframework that focuses on simplicity and interoperability
Create PHP applications simpler and faster with Zend Framework 3.
  
  

Happy PHPing,

http://info.zend.com/P000r0jLAX0H540U0zUC6R0

https://framework.zend.com/blog/2016-06-28-zend-framework-3.html

https://docs.zendframework.com/tutorials/migration/to-v3/overview/



» Leer más, comentarios, etc...

Variable not found

Lanzados .NET Core, ASP.NET Core y Entity framework Core 1.0 RTM

June 28, 2016 09:04 AM

ASP.NET Core¡Por fin! Tras un desarrollo muy largo y convulso, ayer se presentaron las respectivas versiones 1.0 RTM de .NET Core, ASP.NET Core y Entity Framework Core, junto con actualizaciones de una serie de productos relacionados.

La verdad es que hace tan sólo unos años, presentar la nueva versión de ASP.NET en la conferencia Red Hat DevNation habría resultado una auténtica osadía y probablemente habría acabado con tomates volando hacia el escenario. Pero esto es agua pasada, y este simple gesto es una prueba más de que realmente las cosas han cambiado en Microsoft.

Con el lanzamiento de la versión 1.0 de la infraestructura .NET Core y el conjunto de frameworks basados en ella (ASP.NET, MVC, Entity Framework), iniciamos una nueva época en la que aquél sueño de desarrollar o ejecutar fácilmente aplicaciones .NET en cualquier plataforma es ya una realidad, y con todo el soporte y las bendiciones del gigante de Redmond. Escenarios antes impensables, como desarrollar desde Mac para desplegar en Linux, o crear nuestras aplicaciones en Windows y explotarlas desde un contenedor Docker, son ya posibles.

Estamos ante un reboot en toda regla: todos estos frameworks han sido construidos desde cero teniendo en mente conceptos actuales que ni siquiera existían cuando empezaron a gestarse las versiones iniciales de .NET o ASP.NET "clásicos": la nube, alto rendimiento, escalabilidad, APIs, múltiples dispositivos y plataformas, contenedores, microservicios etc. Y creados usando principios y buenas prácticas que tampoco eran los habituales antaño: inyección de dependencias, clases con responsabilidades limitadas, modularidad, componibilidad, abstracciones basadas en interfaces, pruebas unitarias…

Resumiendo, ayer se lanzaron, entre otras cosas:
Con estas novedades ya tenemos entretenimiento para una temporada, ¿que no? ;)

Y la pregunta del millón: ¿debo migrar ya a ASP.NET Core?

Oficialmente, ASP.NET Core se encuentra ya en RTM, lo que quiere decir que está listo para ser utilizado para desarrollar y explotar aplicaciones reales. Las recomendaciones son:
  • No intentar portar a ASP.NET Core aplicaciones existentes, pues el esfuerzo necesario para ello es comparable a lo que supuso el salto de Web Forms a MVC. Si fuera necesario hacerlo, se recomienda afrontarlo más como una reescritura que como una migración.
     
  • Sí serían candidatas a darle la oportunidad a ASP.NET Core aquellas aplicaciones que vayan a desarrollarse desde cero, o bien cuando sean necesarias características exclusivas de este nuevo framework como el soporte multiplataforma (por ejemplo, si necesitamos desplegar sobre Docker).
Y ahora hago yo mi aportación personal al respecto ;) Abstrayéndonos un poco del entusiasmo que despiertan estas novedades y de las ganas que sin duda todos tenemos de hincarle el diente en proyectos reales, hemos de ser conscientes de que estamos ante productos que acaban de salir del horno, aún incompletos en algunos aspectos, y que seguirán evolucionando durante los próximos meses. Aún su ecosistema y comunidad son relativamente pequeños, y al romper con las versiones anteriores hay puntos en los que partiremos desde cero.

Mi recomendación, por tanto, sería actuar con prudencia y estudiar detenidamente las necesidades que tenemos antes de embarcarnos en una aventura que puede ser costosa; simplemente evaluemos los entornos de explotación a los que nos dirigimos, dependencias externas (motores de bases de datos, componentes de terceros…), intención de reutilizar de código existente, las características que necesitamos y no están aún implementadas en Core, el tooling, y muchas otras cosas que nos podrían comprometer en el futuro. Eso sí, una vez la evaluación resulte positiva, seguro que disfrutamos con estos nuevos marcos de trabajo y las posibilidades que nos ofrecen :)

Por último, os dejo algunos enlaces por si queréis ampliar información:

Publicado en Variable not found.

» Leer más, comentarios, etc...

Poesía Binaria

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

June 27, 2016 08:04 AM

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.

» Leer más, comentarios, etc...

Variable not found

Enlaces interesantes 247

June 27, 2016 06:40 AM

Enlaces interesantesAhí van los enlaces recopilados durante la semana pasada. Espero que os resulten interesantes. :-)

.NET

ASP.NET

.NET Core / ASP.NET Core

Azure / Cloud

Conceptos/Patrones/Buenas prácticas

Html/Css/Javascript

Visual Studio/Complementos/Herramientas

Otros

Y para finalizar, ahí tenéis un interesante Podcast donde Bruno Capuano y Pedro J. Molina charlan sobre contenedores y Docker para dar sentido a esos ratos muertos que pasamos en el coche o en el metro cada día :)



Publicado en Variable not found

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

FileOptimizer 8

June 26, 2016 03:30 PM

FileOptimizer 8 lleva ya un tiempo entre nosotros, concretamente desde finales de 2015, sobre el que he ido aplicando ya 4 actualizaciones. Sin embargo desde Estadísticas de FileOptimizer, que nos os mantenía al corriente. La falta de tiempo, y porque no, también la creciente complejidad del proyecto, unido a que no hay colaboradores que ayuden [...]

» Leer más, comentarios, etc...

Variable not found

Ganadores del sorteo de componentes y herramientas de Telerik

June 26, 2016 10:36 AM

TelerikProbablemente haya cosas mejores que hacer un domingo por la mañana, pero pocas tan gratificantes como ir a votar y después ponerse a repartir regalos :)

Así que, siguiendo la tradición, nos hemos reunido un servidor y su habitual instancia de System.Random para echar en el bombo las papeletas virtuales y elegir al azar los ganadores del sorteo de licencias de la suite DevCraft Complete de Telerik.

Y hoy la suerte ha señalado a:

Carlos Gómez @devcfgc
Bilbao
Luis Felipe Gil @lamaslg
Madrid
¡Enhorabuena! En breve me pondré con contacto con vosotros para facilitaros vuestras licencias. Y muchas gracias a los que no habéis tenido tanta suerte, pero no desesperéis que todavía tendréis alguna oportunidad más :)

Me gustaría agradecer también a Telerik su gran apoyo a la celebración del aniversario del blog, que ha sido espectacular.

Ah, y mientras comenzamos el próximo sorteo, no olvidéis que por ser lectores del blog ¡aún podéis conseguir vuestro libro gratis de O'Reilly! Daos prisa porque el tiempo se acaba y en breve acabará la promoción :)

Pero seguid atentos al blog, porque el próximo será ya el último sorteo… ¿alguien había dicho que le gustaría tener una licencia de Resharper? ;)

Publicado en Variable not found

» Leer más, comentarios, etc...

Blog Bitix

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

June 26, 2016 10:00 AM

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.

» Leer más, comentarios, etc...

Blog Bitix

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

June 24, 2016 01:30 PM

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.

» Leer más, comentarios, etc...

Picando Código

¡Felices 20 años Nintendo 64!

June 23, 2016 05:00 PM

Nintendo 64Hoy hace 20 años del lanzamiento del Nintendo 64 en Japón. Aprovecho la oportunidad para celebrar esta consola que tantos ratos de diversión nos dió y sigue dando.

Los primeros datos de la nueva consola de Nintendo llegaban por la revista Club Nintendo  en esos tiempos. Ahí veíamos desde los inicios las características del Ultra 64, nombre que fue cambiado a Nintendo 64 antes de su lanzamiento oficial. Mostraban fotos de prototipos, presentaciones en distintos eventos de videojuegos y tecnología, y potenciales juegos.

El control parecía demasiado grande en las fotos y la transición a 3D de Mario y otros personajes de la familia no terminaba de convencer. Pero todo cambió cuando pudimos probarlo.

Nintendo 64

Tengo grabada en mi memoria la primera vez que usé un Nintendo 64. Estaba con mi familia recorriendo el centro de la ciudad de Maldonado. Pasamos caminando por enfrente al local de electrodomésticos de los padres de un amigo y ahí lo vi en un stand en la vidriera. Un Nintendo 64 conectado a un televisor con el juego Super Mario 64. Dejé que mi familia siguiera camino y me quedé ahí a mirar a través de la vidriera.

Enseguida confirmé que la transición de Mario a 3D había sido un éxito. Los gráficos súper coloridos y el castillo en 3D, con los árboles, el agua, y demás detalles se veían espectaculares. Al rato sale del comercio (creo que) la madre de mi amigo, me saluda y me pregunta “¿Querés entrar a probarlo?”. Me encantaría poder ver mi cara en ese momento. Obviamente dije que sí, y entré a jugar Super Mario 64.

Al pararme del lado de adentro de la vidriera frente al stand me detuve unos segundos a admirar la consola. Antes de agarrar el control lo examiné con la mirada un rato. El miedo de que fuera demasiado grande como mostraban las fotos desapareció enseguida. Y al levantarlo para empezar a jugar se sintió súper cómodo y distinto a todo lo que había venido antes. Así estuve un buen rato jugando hasta que mi familia me encontró y tuve que irme. Obviamente volví a jugar con este amigo varias veces, recuerdo también haber probado Wave Race 64 y sorprenderme con los gráficos del agua de esa época.

Estuve muchos años jugando Nintendo 64 en lo de amigos. La primera vez que jugué Starfox 64 también me quedó bastante grabada. Mi primo me invitó a la casa de uno de sus amigos que además de tener un Nintendo 64 había adquirido recientemente el juego. Nos encantó, pasamos horas jugando esa tarde, y llegamos a vencer a Andross.

Hubo un verano en el que me prestaron un Nintendo 64 que no usaban mucho. Tenía los juegos Perfect Dark y The Legend Of Zelda: Ocarina Of Time, entre otros. Además de terminar la aventura de Ocarina of Time, ese verano pasé noches enteras jugando Perfect Dark multiplayer. Estos dos juegos, además de ser de los mejores que dió la consola, siguen siendo de mis favoritos.

Nintendo 64 juegos

Otro título que consumió muchas horas de mi vida fue Mario Kart 64. La fórmula había sido exitosa en el Super Nintendo, pero la versión en 64 fue la definitiva en su momento. Incluso recuerdo en épocas del blog postear de fines de semana enteros jugando y compitiendo multiplayer en los campeonatos y modo batalla. Todavía hoy es un excelente juego en el que desafiar a otras personas.

Eventualmente pude ahorrar hasta adquirir un Nintendo 64 y desde entonces ha estado prácticamente siempre conectado a mi televisor. Lo genial de su biblioteca de juegos es que hay varios juegos para disfrutar solo como Super Mario 64, Starfox 64 y The Legend Of Zelda: Ocarina Of Time. Pero cuando se trata de jugar con más gente, Mario Kart 64, Smash Bros. 64, Perfect Dark (y/o Goldeneye) eran insuperables.

Últimamente el juego que más he jugado es F-Zero X. Lo descubrí medio tarde, pero requiere bastante habilidad y tiempo dominarlo. Por eso como desafío es bastante entretenido, y es un buen juego para medir lo gastado de las palanquitas de los controles del Nintendo 64. Por suerte hay esperanza para esas palanquitas rotas, veremos qué tal terminan estos proyectos que intentan proveer una solución.

Después de tantos años Nintendo sigue apostando a innovar en el área de videojuegos. Su éxito con Wii fue increíble, y si bien no lograron lo mismo con Wii U, habrá que ver cómo innovan con su próxima consola nombre clave Nintendo NX.

Gracias Nintendo 64 por tantas horas de escape a otros mundos y diversión. Espero que mi querido 64 siga funcionando por 20 años más.
Me dieron ganas de jugar…

Nintendo 64

» Leer más, comentarios, etc...

Bitácora de Javier Gutiérrez Chamorro (Guti)

Clipper y C

June 23, 2016 07:32 AM

A nivel informático, recuerdo con mucho cariño, la época de principios de los años 90. En aquel momento, bastaba con saber lenguaje C y Clipper. MS-DOS 3.30 era el sistema operativo más difundido, acababa de lanzarse DR-DOS 5 y MS-DOS 5 mientras que MS-DOS 6 y DR-DOS 6.0, estaban aún por salir. Se usaba Windows [...]

» Leer más, comentarios, etc...

Poesía Binaria

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

June 22, 2016 08:44 AM

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.

» Leer más, comentarios, etc...

Koalite

Ni titulitis, ni cuñadismo

June 20, 2016 03:22 PM

Yo soy Ingeniero Superior en Informática y estoy orgulloso de ello. Terminé la carrera en el año 2001, después de 5 años en los que aprendí muchas cosas, algunas más útiles y otras menos, pero nunca me he arrepentido del tiempo y el esfuerzo que dediqué a ello.

Si cuento esto es porque la semana pasada hubo cierto revuelo con la campaña Informática Solución YA, en la que algunas asociaciones de Ingenieros Informáticos volvieron a reclamar una regulación para nuestro sector y, como ingeniero que puede ser regulado, creo que no está de más expresar mi opinión.

Titulitis no, gracias

Que el sector de la informática tiene muchos problemas no es nuevo. Precisamente hace poco me quejaba de que lo peor de desarrollar software es tener que tratar con empresas y desarrolladores muy poco profesionales.

¿Es la solución que el estado regule quién se puede dedicar a desarrollar software y en que condiciones? Rotundamente, no.

Para empezar, no creo que la intervención estatal, en general, sea una buena salida para casi nada, y creo que debería ser siempre lo más limitada posible.

Soy consciente de que ese es un argumento que tiene unas implicaciones mayores con las que no todo el mundo estará de acuerdo, por lo que no voy a ahondar en él, sino que me voy a centrar en aspectos más prácticos.

Se supone que uno de los objetivos de la regulación es garantizar a los consumidores que el software que se produce tiene la calidad adecuada, y de alguna manera se asume que la cualificación necesaria para desarrollar software de calidad es algo que se puede medir con un título.

Ójala fuese así. Sería mucho más sencillo encontrar empresas adecuadas a las que encargarles proyectos de desarrollo.

La realidad es que tener un título no garantiza nada más allá de haber aprobado x exámenes. De hecho, puedes tener un título de ingeniero informático y no haber ejercido como tal en tu vida (y conozco más de un caso): ¿esa persona está más o menos preparada para desarrollar una aplicación que alguien que se dedica a ello continuamente durante 10 años?

Las reivindicaciones se basan en títulos (porque para eso son colegios de Ingenieros), pero supongamos que cambiamos un título por una certificación. Por un examen o un permiso renovable, como el carnet de conducir, pero de desarrollador de aplicaciones. ¿Tiene sentido? ¿Quién va a establecer el contenido del examen de certificación? ¿Cada cuánto tiempo se va a renovar? ¿Hay uno genérico o depende del tipo de aplicación? ¿De verdad esto nos lleva a alguna parte?

Me vais a disculpar, porque seguro que soy un mal pensado, pero a mi todo esto de regular me suena a pretender adquirir unos privilegios. Una regulación del sector sería más útil para los ingenieros que para los clientes y usuarios de aplicaciones informáticas, y me parece mal que el estado regule de esa manera.

Pero hay que valorar el conocimiento

Cuando se entra en estos temas se corre el riesgo de pasar de un extremo al otro. Del elitismo de “si no eres ingeniero no puedes dedicarte a esto” al “estudiar una carrera no sirve para nada, lo que cuenta es la experiencia”.

Es fácil encontrar artículos en los que se califica estudiar una carrera como una gran pérdida de tiempo, y muchas veces se tiende a valorar certificaciones y cursos que nos permitan ponernos al día rápidamente en las cosas que de verdad se usan mucho más que el conocimiento profundo, de carácter más teórico, que puedes alcanzar con otro tipo de formación.

Estudiar una carrera, al igual que cualquier otro tipo de formación, no garantiza que aprendas nada. Para eso necesitas dar con unos profesores no demasiado malos (tampoco hace falta que sean excepcionalmente buenos) y poner bastante de tu parte.

En una carrera se enseñan muchas cosas que, a priori, no sirven para nada, pero que luego resultan ser la base de muchas de esas cosas que se enseñan en los cursos que permiten ponerte al día rápidamente en la tecnología de turno. Si no conoces esos fundamentos, acabarás volviéndolos a estudiar muchas veces en otros tantos cursos distintos, bajo nombres diferentes.

No hay nada que te impida aprender por tu cuenta lo mismo que se enseña en una carrera, pero en general te va a costar más. Siempre es más complicado aprender sólo que aprender guiado. Eso lo saben hasta los artesanos, con sus maestros y aprendices.

Un título no garantiza que se hayan adquirido esos conocimientos fundamentales, pero tener 10 años de experiencia tampoco garantiza nada. Puedes tener 10 años de experiencia y no tener ni idea de desarrollar software. Y puedes tener 10 años de experiencia y un título, y tener menos idea aún. Pero eso no quita que, en general, alguien con más experiencia tienda a ser mejor, y alguien con más formación, también.

Al final es muy sencillo. Tan sólo se trata de adquirir las competencias necesarias para desarrollar un trabajo.

Por el hecho de que yo acabase una carrera hace 15 años no creo que tenga más o menos derecho que otro a dedicarme profesionalmente al desarrollo de software. Lo que debería avalarme es mi capacidad para desarrollar software, no cómo la haya adquirido.

No hay posts relacionados.

» Leer más, comentarios, etc...

Blog Bitix

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

June 18, 2016 11:00 AM

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.

» Leer más, comentarios, etc...

Blog Bitix

Atajos de teclado básicos de la terminal en GNU/Linux

June 17, 2016 04:00 PM

Aprender las combinaciones de teclas de aquellas aplicaciones que usamos frecuentemente y durante mucho tiempo nos ayuda a hacer las cosas en menos tiempo y de forma más sencilla. Cada aplicación tiene los suyos propios, en este artículo los de la terminal con el intérprete de comandos bash para GNU/Linux.

Linux
GNU

Si no conoces lo que estás buscando una interfaz gráfica es una buena forma de descubrir cosas, si conoces exactamente lo que buscas y si lo tienes que hacer de forma repetida es tediosa y lenta. La terminal en GNU/Linux sigue siendo una poderosa herramienta para realizar multitud de tareas. Entre sus ventajas son realizar la tareas de forma mucho más directa y simple que con una interfaz gráfica o la posibilidad de automatizar tareas repetitivas en un script bash o en un lenguaje de programación como Python. Entre las desventajas de la línea de comandos está que no suele ser tan intuitiva como una interfaz gráfica. Dadas las ventajas de la terminal o línea de comandos para algunas personas su uso es muy frecuente y en GNU/Linux es común tener que usarla en algún momento, conocer las combinaciones de teclas que podemos usar la tarea será más fácil y la haremos rápidamente.

En el intérprete de la terminal bash podemos usar las siguientes combinaciones de teclas:

  • Ctrl+a: lleva el cursor al inicio de la línea de comandos.
  • Ctrl+e: lleva el cursor al final de la línea de comandos.
  • Ctrl+l: limpia la terminal, similar a lo que hace el comando clear.
  • Ctrl+u: limpia desde la posición del cursor hasta el inicio de la línea. Si se está al final limpia la línea entera.
  • Ctrl+k: limpia desde la posición del cursor hasta el final de la línea. Si se está al inicio limpia la línea entera.
  • Ctrl+h: hace lo mismo que la tecla backspace, borra el caracter inmediatamente anterior a la posición del cursor.
  • Ctrl+w: borra la palabra inmediatamente antes del cursor.
  • Alt+d o Esc+d: borra la palabra siguiente después del cursor.
  • Ctrl+p: establece la línea de comandos con el último comando introducido.
  • Ctrl+r: inicia la búsqueda de comandos usados anteriormente, tecleando parte de un comando usos anteriores que hayamos realizado incluyendo las opciones y parámetros. Hecha una búsqueda pulsando de nuevo la combinación de teclas encontraremos coincidencias anteriores.
  • Ctrl+c: termina el proceso que se esté ejecutando, útil para recuperar el control del sistema.
  • Ctrl+d: sale de la terminal, similar al comando exit.
  • Ctrl+z: suspende la ejecución del proceso que se está ejecutando y lo pone en segundo plano, con el comando fg podremos volver a continuar su ejecución.
  • Ctrl+t: intercambia la posición de los dos caracteres antes del cursor, útil para corregir malos tecleos.
  • Esc+t: intercambia la posición de las dos palabras antes del cursor, útil para corregir malos tecleos.
  • Alt+f: mueve el cursor al inicio de la palabra siguiente de la línea, lo mismo que Ctrl+right en la terminal de GNOME.
  • Alt+b: mueve el cursor al inicio de la palabra anterior de la línea, lo mismo que Ctrl+left en la terminal de GNOME.
  • Tab: autocompleta comandos o rutas de directorios o archivos.

Poner comandos en segundo plano es útil si un proceso deja el sistema sin respuesta o queremos introducir otro antes de que termine el primero. Con tres comandos podemos manejar los procesos en primer y segundo plano:

  • jobs: con este comando podremos ver la lista de procesos en segundo plano, con información de si están detenidos/suspendidos o en ejecución además del identificativo asignado para usar en los comandos fg y bg.
  • fg: pone en primer plano un proceso, si estaba suspendido reanuda su ejecución.
  • bg: continua la ejecución del proceso pero lo deja en segundo plano, si emite contenido a la terminal se mostrará y quizá nos moleste al seguir trabajando.
  • kill: con el identificativo del proceso en segundo plano y un símbolo de porcentaje por delante podemos enviar la señal de terminado del proceso. Ejemplo, kill %1.
  • Añadiendo un ampersand, &, al final del comando pondremos el comando en ejecución pero en segundo plano directamente.

Las anteriores combinaciones de teclas son del intérprete de comandos bash, el emulador de terminal que usemos también incorpora algunas combinaciones de teclas más. En el caso del emulador del terminal de GNOME podemos usar las siguientes combinaciones muy útiles:

  • Ctrl+Shift+f: abre un diálogo para hacer una búsqueda de texto en la salida de la terminal.
  • Ctrl+Shift+g: busca la siguiente ocurrencia de la búsqueda previa en la terminal.
  • Ctrl+Shift+h: busca la anterior ocurrencia de la búsqueda previa en la terminal.
  • Ctrl+Shift+c: copia el texto seleccionado de la terminal al portapapeles.
  • Ctrl+Shift+v: pega el texto del portapapeles en la línea de comandos.
  • Up: establece en la línea de comandos el comando anterior del historial, igual que Ctrl+p.
  • Down: establece en la línea de comandos el siguiente comando del historial.
  • Left Mouse: selecciona líneas de texto de la terminal.
  • Ctrl+Left Mouse: selecciona bloques de texto de la terminal.
Terminal de GNOME con el intérprete de comandos bash

» Leer más, comentarios, etc...

Picando Código

Que la información sea un derecho y no un delito

June 17, 2016 03:00 PM

Copio y pego información de un evento promocionado por Creative Commons Uruguay sobre vigilancia comercial y estatal, el acceso a la información y la reforma de la ley de derechos de autor. Ahí estaremos:

Que la información sea un derecho y no un delito

El próximo miércoles 22 de junio nos vamos a juntar para discutir sobre el lugar de la información en la nueva agenda de derechos. En el marco de la semana de acción global de solidaridad por la situación de privación de libertad de Julian Assange, desde Proderechos y Creative Commons Uruguay invitamos a todas y todos a discutir sobre la vigilancia comercial y estatal, el acceso a la información y la reforma de la ley de derechos de autor. La actividad va a tener lugar el miércoles 22 de junio a las 19 hs en Casa Tomada (Soriano 762 esquina Ciudadela, Montevideo).

¿Qué porción de nuestra privacidad estamos dispuestos a ceder frente a los nuevos medios de vigilancia pública y privada? ¿Pueden los estados limitar nuestro derecho a la privacidad para brindarnos mayor seguridad? ¿Cómo se regula en Internet la libertad de expresión y la protección de la intimidad? ¿Hasta dónde llega el derecho de acceso a la información de los ciudadanos, frente a estados y corporaciones? ¿Puede considerarse el conocimiento una propiedad privada? ¿Las acciones cotidianas de acceso al conocimiento e información -como sacar fotocopias, o descargar información de internet- deben seguir siendo delitos?

Como panelistas estarán: Gabriel Delacoste (politólogo), Mariana Fossatti (socióloga, integrante de Creative Commons Uruguay), Sebastián Sabini (diputado) y Fabrizio Scrollini (abogado, integrante de DATA Uruguay). Moderará Victoria Carranza, integrante de Proderechos. Se proyectarán grabaciones de las intervenciones de Julian Assange y otros destacados activistas internacionales.

Visitá también el evento en Facebook.

» Leer más, comentarios, etc...

Meta-Info

¿Que es?

Planeta Código es un agregador de weblogs sobre programación y desarrollo en castellano. Si eres lector te permite seguirlos de modo cómodo en esta misma página o mediante el fichero de subscripción.

rss subscripción

Sponsors

Puedes utilizar las siguientes imagenes para enlazar PlanetaCodigo:
planetacodigo

planetacodigo

Si tienes un weblog de programación y quieres ser añadido aquí, envíame un email solicitándolo.

Idea: Juanjo Navarro

Diseño: Albin