Recomendaciones de anime – Temporada de invierno 2015

[anime]

Anime de la temporada de invierno 2015

Contrastando con el vacío de recomendaciones de la temporada anterior, en esta ocasión hemos tenido una gran temporada con muchas series buenas:

Death Parade

Hace dos años recomendé una OVA llamada Death Billiards por su originalidad e intensidad. Imaginad mi alegría cuando me encontré con una temporada completa siguiendo su mismo concepto. El resultado ha sido muy bueno, pero no exento de algunos problemas. En algunos momentos, la trama puede ser un tanto repetitiva, y al expandir el universo para añadir a nuevos personajes y dar explicación al funcionamiento del mismo, se quedan algunos puntos cogidos por lo pelos. Sin embargo la originalidad sigue ahí, las historias son interesantes y los nuevos personajes complementan al protagonista. En conjunto un gran anime.

Shigatsu wa Kimi no Uso

Reconozco que tengo debilidad por los animes donde la música tiene mucho peso en la historia. En esta ocasión tenemos la historia de un pianista traumatizado por la muerte de su madre y como su vida cambia tras conocer a una misteriosa violinista. Pese a estar basada en el instituto, se tocan temas muy adultos, y francamente la historia es un poco dramón, con clara intención de sacarte las lágrimas, lo cual consigue. Sin embargo es el típico anime que te engancha, los capítulos se pasan volando, y te deja con ganas de más.

Parasyte – the maxim

La verdad es que con ese nombre y viendo el primer capítulo, parece mentira lo bueno que ha acabado siendo este anime. Diría que es uno de los mejores shonen de los últimos tiempos. La trama no es muy compleja, pero está muy bien llevada. Los personajes son interesantes, la animación  y diseños son buenos, y las batallas son emocionantes.

Durarara!! X2

La primera temporada de Durarara!! me encantó. No la pude recomendar en su momento porque todavía no existía este blog, pero sin duda la habría recomendado. Buenos personajes, historia y animación. En esta segunda temporada continua la historia donde se quedó la primera, y cada vez hay más fuerzas chocando en Ikebukuro. Además parece que no tardaremos mucho en tener una tercera temporada.

Un parámetro de la directiva de AngularJS tiene valor undefined

[programación]

Estaba modificando una directiva de un tercero y me estaba volviendo loco con un valor que siempre estaba undefined. La directiva era sencilla y no entendía cual era el error.

La definición del scope dentro de la directiva es esta:

scope: {
  searchParam: '=ngModel',
  suggestions: '=data',
  onType: '=onType',
  formId: '=formId',
  onSelect: '=onSelect',
  autocompleteRequired: '='
}

Y el uso de la directiva es este:

<autocomplete
    ng-model="vm.sCompanyName"
    data="vm.aInsuranceCompanies"
    form-id="bikeInsuranceAlert"
    on-type="vm.autocompleteChange">
</autocomplete>

El valor que me interesa obtener es el formId. ¿Veis el error? Es sutil…

form-id="'bikeInsuranceAlert'"

Faltaban unas comillas simples dentro de las dobles para obtener el valor del ID como una cadena. Lo que AngularJS estaba interpretando es que quería obtener el valor de una variable llamada bikeInsuranceAlert dentro del scope. Evidentemente esta variable no existe, y el valor asignado era undefined.

Que traicionero es AngularJS en ocasiones…

Como resolver conflictos entre dos ramas remotas de un repositorio y su bifurcación (fork) en Git

[programación]

La situación es la siguiente: Tenemos un repositorio remoto en Bitbucket que es el principal, y después tenemos una bifurcación (fork) para cada desarrollador, los cuales suben sus cambios mediante solicitudes de integración (pull request). El problema surge al intentar sincronizar ramas entre los distintos repositorios y aparecen conflictos en remoto.

Solucionar este tipo de conflictos en local es sencillo mediante por ejemplo NetBeans, por lo que la solución pasa por convertir el conflicto remoto en un conflicto local.

Supongamos que la rama conflictiva es feature/nueva-funcionalidad

1. Configuramos el repositorio principal como repositorio remoto

git remote add upstream https://Usuario@bitbucket.org/Propietario/Repositorio-principal.git
git fetch upstream

2. Nos situamos en nuestra rama local

git checkout feature/nueva-funcionalidad

3. Obtenemos los posibles cambios desde nuestro repositorio remoto bifurcado

git merge origin/feature/nueva-funcionalidad

4. Obtenemos los cambio del repositorio principal

git merge upstream/feature/nueva-funcionalidad

5. Aquí aparecerán los conflictos que nos impedían hacer el merge entre repositorios remotos. Resolvemos los conflictos y los anotamos (commit). Al terminar ya podemos subir los cambios a nuestro repositorio remoto bifurcado.

git push origin feature/car-insurance-alert

curl_setopt(): CURLOPT FOLLOWLOCATION cannot be activated when an open_basedir is set

[programación]

El mensaje de error completo es este:

Severity: Warning
Message:  curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set
Filename: src/Mandrill.php
Line Number: 68

Este es un problema conocido de la API PHP de Mandrill, y existe un Pull Request con la solución creado en abril de 2014, pero por el motivo que sea, no han añadido la corrección al repositorio principal.

Yo utilizo Composer y Packagist para gestionar las dependencias en mis proyectos, por lo que como solución temporal puedes modificar el fichero Mandrill.php con las correcciones, pero esto significa repetir el mismo proceso en todos los entornos de desarrollo, y es fácil olvidarse de hacerlo cuando han pasado unos meses.

Como solución más robusta, he creado un fork the la librería de Mandrill, y la he subido a Packagist para que pueda ser usada. Es tan sencillo como añadir esto a tus “require” en el composer.json:

"carlos_llongo/mandrill": "dev-master"

O también puedes usar:

composer require "carlos_llongo/mandrill:dev-master"

Como saber si un usuario tiene acceso por SSH

[linux]

Tan fácil como mirar el fichero /etc/passwd

Aquí vemos el listado de usuario con la terminal que tienen asignada. Si la terminal no existe, como por ejemplo /bit/false, el usuario será desconectado inmediatamente al hacer login.

Para solucionarlo, editamos el fichero y le damos un terminal válido, como por ejemplo /bin/bash

La solución original en StackOverflow.

Guardar una cookie con JavaScript puro

[programación]

AngularJS tiene un módulo para guardar cookies, pero por desgracia no permite establecer la fecha de expiración de la cookie, por lo que la cookie es borrada al final de la sesión.

Hay plugins para AngularJS y para JQuery que permite crear cookies de forma sencilla y establecer la fecha de expiración, pero no quería añadir una libraría más solo para guardar una cookie. Así que esta es la forma de hacerlo usando únicamente JavaScript puro:

var dExpirationDate = new Date();
dExpirationDate.setTime(dExpirationDate.getTime() + (365*24*60*60*1000));
var sExpirationDate = "expires=" + dExpirationDate.toUTCString();
document.cookie = "cookieName=cookieValue; " + sExpirationDate;

Recomendaciones de anime – Temporada de otoño 2014

[anime]

Anime de la temporada de otoño 2014

No sabría decir si la calidad del anime está bajando, o si yo me estoy volviendo más crítico, pero cada vez cuesta más encontrar anime que recomendar. Esta temporada ha ocurrido lo que no ha ocurrido en tres años y medio de Recomendaciones de anime, y es que por primera vez no tengo nada que recomendar. La que más posibilidades tenía era Shingeki no Bahamut GENESIS, que la verdad empezó muy bien. Me recordaba a Cowboy Bebop, pero ambientada en un mundo de fantasía medieval. El problema es que a mitad seríe la trama descarrila, y pierde mucho de su interés.

Otra en la que tenía esperanzas era la segunda temporada de Psycho-Pass, pero tras verme tres capítulos perdí el interés. No terminó de engancharme. La sigo teniendo pendiente de ver, así que tal vez cuando la acabe actualizaré mi valoración.

Cómo saber cuando se actualizó una web por última vez

[internet] [programación]

Evidentemente esto solo funcionará en páginas estáticas, pero más de una vez me he encontrado con alguna librería de PHP o JQuery que no mostraban ninguna fecha de última actualización en su web. Para esas situaciones, podemos abrir el Firebug y en la consola escribir lo siguiente:

javascript:alert(document.lastModified)

Saltará una alerta con la fecha de la última modificación.

Comprobar si existe un elemento con AngularJS y ejecutar una función solo si existe

[programación]

Esta es la situación: Queremos ejecutar un plugin de JQuery sobre un elemento que se crea dinámicamente con un ng-repeat dentro una plantilla de AngularJS. Es decir, no podemos inicializar el plugin hasta que se ha cargado la plantilla y se han creado los elementos.

Tenemos un controlador específico para dicha plantilla, por lo que realizando la comprobación aquí, solucionamos la primera parte del problema. Investigando un poco, veo que la solución más popular es asignar una directiva al ng-repeat, que detectará cuando se ejecute la última iteración y lanzará un evento para ser recogido por el controlador, y entonces ya podríamos ahí ejecutar el plugin.

En Stackoverflow tenemos un ejemplo de esta aproximación, y en Nodewiz.biz tenemos otro ejemplo muy similar.

El caso es que esta aproximación me parece tremendamente rebuscada, aunque no dudo que cumple con el espíritu de AngularJS. Mi aproximación es más sencilla, aunque sospecho que no es del todo correcta, y me gustaría mejorarla con el tiempo:

$scope.bTooltipsterExists = false;

$scope.$watch(
function(){
    if(angular.element('.tooltipster').length){
        $scope.bTooltipsterExists = true;
        return true;
    }

    return false;
},
function(){
    if($scope.bTooltipsterExists){
        $(".tooltipster").tooltipster({
            trigger: 'click',
            delay: 0
        });
    }
});

Básicamente tengo un $watch que lo que hace es observar una función. Esta función busca los elementos que se crearán con el ng-repeat y tendrán la clase .tooltipster. La segunda función es la que se ejecuta cuando hay un cambio en el valor devuelto por la primera función. Es decir, cuando la primera función pase de devolver false a devolver true, se ejecutará el plugin.

Añado una segunda comprobación con la variable $scope.bTooltipsterExists porque la primera vez que se ejecuta el $watch, como no tiene una variable de referencia anterior, siempre se ejecuta la segunda función, y con esto lo evitamos.

Reseña de juego – Destiny

[videojuegos]

Últimamente tenía muy abandonados los videojuegos. Estaban saliendo pocas cosas para Xbox 360 y mi PC no da para jugar, así que hace un par de meses me compre una Playstation 4. Mi objetivo es poder pasarme un juego cada mes e iré comentando por aquí mis impresiones de cada uno.

Portada del juego Destiny

Empiezo con Destiny, un juego que tenía un expectación brutal y que estaba destinado a echarle horas y horas jugando con amigos. Esto se cumplió al principio, el sistema de juego es excelente, los gráficos son increíbles y jugando con amigos es muy divertido. El problema es que Destiny deja de ofrecer nuevas experiencias muy rápidamente, y entonces se convierte en una tarea muy repetitiva. Sigue siendo entretenido, de esa misma manera en la que te puedes poner a ver la tele y desconectar un rato, pero siendo que mi tiempo de ocio es limitado y tengo que repartirlo entre múltiples aficiones, repetir lo mismo una y otra vez en Destiny me parece una pérdida de tiempo.

Si hay algo que me decidió a dejar el juego, fue el sistema de loot (los ítems que sueltan los enemigos derrotados). Puedes pasar horas y horas sin obtener nada relevante. Todo el sistema parece estar diseñado para obligarte a invertir una cantidad de tiempo descomunal para lograr una mínima mejora en tu personaje. Todo con el fin de hacerte pensar que el juego es más largo de lo que es, intentando ocultar su falta de contenido.

¿Lo recomiendo? NO